前言
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,并分別介紹了兩種持久化機制的原理,通過對兩種持久化機制的對比分析了兩種持久化機制各自的優點和缺點,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/255259.html
標籤:其他
下一篇:路由技術——OSPF
