前言
Redis
作為一款記憶體資料庫,被廣泛使用於快取,分散式鎖等場景,那麼假如斷電或者因其他因素導致 Reids
服務當機,在重啟之後資料會丟失嗎?
Redis 持久化機制
Redis
雖然是定義為一個記憶體資料庫,但是其也支援資料的持久化,在 Redis
中提供了兩種持久化機制:RDB
持久化和 AOF
持久化。
RDB 持久化機制
RDB
全稱為:Redis DataBase
,是 Redis
當中預設的持久化方案。當觸發持久化條件時,Redis
預設會生成一個 dump.rdb
檔案,Redis
在重啟的時候就會通過解析 dump.rdb
檔案進行資料恢復。
RDB 機制觸發條件
RDB
持久化機制有兩種觸發方式:自動觸發和手動觸發。
自動觸發
自動觸發方式也可以分為三種:
- 執行
flushall
命令(flushdb
命令不會觸發)時,不過此時生成的dump
檔案內的資料是空的(dump
檔案還會儲存一些頭資訊,所以檔案本身是有內容的,只是沒有資料),沒有什麼太大的實際意義。 - 執行
shutdown
命令時會觸發生成dump
檔案。 - 通過配置檔案自動生成,
Redis
中配置檔案預設配置如下,只要達到這三個條件中的任意一個,就會觸發Redis
的RDB
持久化機制。
save 900 1 //900秒內至少有1個key被新增或者更新
save 300 10 //300秒內至少有10個key被新增或者更新
save 60 10000 //60秒內至少有10000個key被新增或者更新
手動觸發
除了自動觸發,Redis
中還提供了 2
個手動觸發 RDB
機制的命令(這兩個命令不能同時被執行,一旦一個命令正在執行中,另一個命令會被拒絕執行):
save
:這個命令會阻塞Redis
伺服器程式,直到成功建立RDB
檔案,也就是說在生成RDB
檔案之前,伺服器不能處理客戶端傳送的任何命令。bgsave
:父程式會執行fork
操作來建立一個子程式。RDB
檔案由子程式來負責生成,父程式可以正常處理客戶端傳送的命令(這裡也是Redis
不僅僅只是單執行緒的一個體現)。
如果想要知道上一次成功執行 save
或者 bgsave
命令的時間,可以執行 lastsave
命令進行檢視,lastsave
命令返回的是一個 unix
時間戳。
RDB 機制相關配置檔案
除了上面提到的觸發生成 rdb
檔案的配置引數,RDB
持久化機制還有如下一些相關命令:
-
dir
:rdb
檔案生成目錄。預設是./
(當前目錄),可以執行命令config get dir
進行檢視,如下圖所示說明當前dump
檔案生成目錄為/usr/local/redis-5.0.5/bin
: -
dbfilename
:rdb
檔名。預設是dump.rdb
。 -
rdbcompression
:rdb
檔案是否是LZF
壓縮檔案。預設是yes
。 -
rdbchecksum
:是否開啟資料校驗。預設是yes
。
RDB 機制優點
RDB
是一個非常緊湊的壓縮檔案,儲存了不同時間點上的檔案,非常適合用來災備和資料恢復。RDB
最大限度地提高了Redis
的效能,因為Redis
父程式需要做的唯一的工作就是派生一個子程式來完成剩下的工作,父程式永遠不會執行磁碟I/O
或類似的耗時操作。- 與後面介紹的
AOF
持久化機制比較,RDB
方式恢復資料的速度更快。
RDB 機制缺點
RDB
無法做到實時備份,所以如果Redis
因異常停止工作而沒有正確的關機,那麼從上一次備份的到異常當機的這一段時間的資料將會丟失。- 2、
RDB
通常需要父程式來執行fork
操作建立子執行緒,所以如果頻繁執行fork
操作而CPU
效能又不是很高的話可能會造成短時間內父程式不可用。
AOF 持久化機制
AOF
全稱為:Append Only File
,是 Redis
當中提供的另一種持久化機制。AOF
採用日誌的形式將每個寫操作追加到檔案中。開啟 AOF
機制後,只要執行更改 Redis
資料的命令時,命令就會被寫入到 AOF
檔案中。在 Redis
重啟的時候會根據日誌內容依次執行 AOF
檔案中的命令來恢復資料。
AOF
和 RDB
最大的不同是:AOF
記錄的是執行命令(類似於 MySQL
中 binlog
的 statement
格式),而RDB
記錄的是資料(類似於 MySQL
中 binlog
的 row
格式)。
需要注意的是:假如同時開啟了 RDB
和 AOF
兩種機制,那麼 Redis
會優先選擇 AOF
持久化檔案來進行資料恢復。
AOF 機制如何開啟
AOF
機制預設是關閉的,可以通過以下配置檔案進行修改
appendonly no //是否開啟AOF機制,預設是no表示關閉,修改為yes則表示開啟
appendfilename "appendonly.aof" //AOF檔名
PS:和 RDB
機制一樣,其生成檔案的路徑也是通過 dir
屬性進行配置。
AOF 機制資料是否實時寫入磁碟
AOF
機制下資料是否實時寫入磁碟,這個和 MySQL
的 redo log
機制很類似,也是需要通過引數來進行控制。
AOF
資料何時寫入磁碟由引數 appendfsync
來進行控制:
appendfsync | 描述 | 備註 |
---|---|---|
always | 寫入快取的同時通知作業系統重新整理(fsync)到磁碟(但是也可能會有部分作業系統只是儘快刷盤,而不是實時刷盤) | Slow, Safest |
everysec | 先寫入快取,然後每秒中刷一次盤(預設值),這種模式極端情況可能會丟失 1s 的資料 | Compromise |
no | 只寫入快取,什麼時候刷盤由作業系統自己決定 | Faster |
AOF 檔案重寫
AOF
機制主要是通過記錄執行命令的方式來實現的,那麼隨著時間的增加,AOF
檔案不可避免的會越來越大,而且可能會出現很多冗餘命令。比如同一個 key
值執行了 10000
次 set
操作,實際上前面 9999
次對恢復資料來說都是沒用的,只需要執行最後一次命令就可以把資料恢復,正是為了避免這種問題,AOF
機制就提供了檔案重寫功能。
重寫原理分析
AOF
重寫時 Redis
並不會去分析原有的檔案,因為如果原有檔案過大,分析也會很耗時,所以 Redis
選擇的做法就是重新去 Redis
中讀取現有的鍵值對,然後用一條命令記錄鍵值對的值。
只使用一條命令也有一個前提,那就是一個集合鍵或者列表鍵或者雜湊鍵內包含的元素不能超過 64
個,一旦超過 64
個,就會使用多條命令來進行記錄。
AOF 重寫緩衝區
AOF
重寫的時候一般都會有大量的寫操作,所以為了不阻塞客戶端的命令請求,Redis
會把重寫操作放入到子程式中執行,但是放入子程式中執行也會帶來一個問題,那就是重寫期間如果同時又執行了客戶端發過來的命令,又該如何保證資料的一致性?
為了解決資料不一致問題,Redis
中引入了一個 AOF
重寫緩衝區。當開始執行 AOF
檔案重寫之後又接收到客戶端的請求命令,不但要將命令寫入原本的 AOF
緩衝區(根據上面提到的引數刷盤),還要同時寫 入 AOF
重寫緩衝區:
一旦子程式完成了 AOF
檔案的重寫,此時會向父程式發出訊號,父程式收到訊號之後會進行阻塞(阻塞期間不執行任何命令),並進行以下兩項工作:
- 將
AOF
重寫緩衝區的檔案重新整理到新的AOF
檔案內。 - 將新
AOF
檔案進行改名並原子的替換掉舊的AOF
檔案。
完成了上面的兩項工作之後,整個 AOF
重寫工作完成,父程式開始正常接收命令。
AOF 機制觸發條件
AOF
機制的觸發條件同樣也分為自動觸發和手動觸發。
- 自動觸發:自動觸發可以通過以下引數進行設定:
auto-aof-rewrite-percentag //檔案大小超過上次AOF重寫之後的檔案的百分比。預設100,也就是預設達到上一次AOF重寫檔案的2倍之後會再次觸發AOF重寫
auto-aof-rewrite-min-size //設定允許重寫的最小AOF檔案大小,預設是64M。主要是避免滿足了上面的百分比,但是檔案還是很小的情況。
- 手動觸發:執行
bgrewriteaof
命令。
注意:bgrewriteaof
命令也不能和上面 RDB
持久化命令 bgsave
同時執行,這麼做是為了避免同時建立兩個子程式來同時執行大量寫磁碟操作,影響到 Redis
的效能。
AOF 機制機制優點
- 使用
AOF
機制,可以自由選擇不同fsync
(刷盤)策略,而且在預設策略下最多也僅僅是損失1s
的資料。 AOF
日誌是一個僅追加的日誌,因此如果出現斷電,也不存在查詢或損壞問題。即使由於某些原因(磁碟已滿或其他原因),日誌已經寫了一半的命令結束,redis-check-aof工具也能夠輕鬆地修復它。- 當
AOF
檔案變得太大時,Redis
能夠在後臺自動重寫。 - 不同於
RDB
的檔案格式,AOF
是一種易於理解和解析的格式,依次包含所有操作的日誌。
AOF 機制機制缺點
- 對於相同的資料集,
AOF
檔案通常比等效的RDB
檔案大。 - 根據
fsync
的具體策略,AOF
機制可能比RDB
機制慢。但是一般情況下,fsync
設定為每秒的效能仍然很高,禁用fsync
後,即使在高負載下,它的速度也能和RDB
一樣快。 - 因為
AOF
檔案是追加形式,可能會遇到BRPOP
、LPUSH
等阻塞命令的錯誤,從而導致生成的AOF
在重新載入時不能複製完全相同的資料集,而RDB
檔案每次都是重新從頭建立快照,這在一定程度上來說RDB
檔案更加健壯。
總結
本文主要介紹了 Redis
的兩種持久化機制:RDB
和 AOF
,並分別介紹了兩種持久化機制的原理,通過對兩種持久化機制的對比分析了兩種持久化機制各自的優點和缺點。