持久化機制
盡管 Redis 是基于記憶體的 key-value 服務,但也可以進行資料的持久化,以便服務重新開機,資料能重新加載進來。
為了盡可能的保證資料不丢失,Redis 為我們提供了好幾種持久化機制:
- RDB:即 Redis Database,在指定的時間間隔裡将 Redis 記憶體資料鏡像下來,儲存到檔案裡。
- AOF:将伺服器對資料的寫操作追加到檔案裡,相當于将所有的邏輯操作都記錄了下來。
- 無持久性:不進行持久化,性能最好。
- RDB + AOF:将 RDB 和 AOF 結合起來,組合它們各自的優點。
下面,我們來看看這些機制吧。
RDB 配置
在
redis.conf
檔案裡我們可以針對 RDB 持久化方式進行設定:
### 快照設定 ###
# save "" 空表示不進行持久化
save 900 1 # 900 秒内如果有1個 key 值改變,則進行持久化動作
save 300 10 # 300 秒内如果有10個 key 值改變,則進行持久化動作
save 60 10000 # 60 秒内如果有10000個 key 值改變,則進行持久化動作
# 如果持久化失敗,則 Redis 不會再進行資料更新操作,直到恢複正常
stop-writes-on-bgsave-error yes
# 是否對持久化的 rdb 檔案進行壓縮儲存
rdbcompression yes
# 是否對持久化的 rdb 檔案進行校驗
rdbchecksum yes
# 要持久化的 rdb 檔案名
dbfilename example.rdb
# 導出目錄
dir /opt/redisdata
RDB 優勢
- 當 Redis 進行持久化動作時,它會先 fork 一個子程序,将資料的寫入交給子程序,而父程序不會涉及到磁盤的 IO 操作,是以 RDB 的性能非常好。
- 如果是在 Unix 系統上,還能充分利用寫時複制機制。也就是子程序和父程序共用相同的記憶體頁面,隻有當子程序或父程序進行修改才會進行複制。這樣節省了對實體記憶體的使用。
- 由于 RDB 檔案隻存儲了某個時刻的記憶體資料,并沒有什麼邏輯指令,是以在進行重新開機恢複時,能很快的加載進來。
RDB 缺點
- 雖然 RDB 的 fork 能使得 Redis 的持久化獨立進行,但是一旦資料量比較大的,就會一直占用 CPU,可能會影響到父程序的進行。
- 前面的 RDB 配置裡我們提到是按一定的時間間隔内去觸發持久化的,但也正是因為這個時間間隔原因,導緻我們将會有一定機率在這段時間内丢失資料。
AOF 配置
同樣的,我們可以在
redis.conf
檔案裡對 AOF 持久化進行配置:
appendonly no # 是否開啟 aof
appendfilename "appendonly.aof" # aof 檔案名
# 同步到磁盤的政策 預設每秒一次
# appendfsync always # 每次
appendfsync everysec # 每秒一次
# appendfsync no # 由作業系統執行,預設Linux配置最多丢失30秒
auto-aof-rewrite-percentage 100 # aof 檔案超過比例則進行重寫
auto-aof-rewrite-min-size 64mb # aof 檔案超過多少則進行重寫
aof-load-truncated yes # 如果 aof 最後的指令有誤,則在重新恢複時忽略。
在上面的配置中,我們看到有關 aof 檔案重寫的配置。之是以需要對 aof 進行重寫,是因為 aof 檔案記錄的是邏輯操作。随着系統運作越久,操作指令将越來越多,日志檔案也就越來越大了,是以需要對其進行重寫,以減少磁盤空間。
當 AOF 進行檔案重寫時,會将記憶體資料重新整理一遍,然後儲存到新檔案裡,接着再将新檔案替換原來的 AOF 檔案。
AOF 優勢
- AOF 讓我們可以以每秒的速度進行持久化,這樣的話可以很大程度的減少資料的丢失。
- AOF 采用追加的方式進行寫檔案,這樣即使持久化失敗,影響較少,而且能夠使用 redis-check-aof 進行修複。
AOF 缺點
- 前面提到過日志會越來越大,需要靠重寫來減少對磁盤的占用。
混合持久化
為了能将 AOF 和 RDB 的優勢結合起來, Redis 在 4.0 之後啟用了混合持久化,它的配置如下:
aof-use-rdb-preamble yes
當開啟了混合持久化後,Redis 會 fork 子程序将記憶體資料以 RDB 格式寫入 AOF 檔案,後面會将重寫緩沖區的增量指令以 AOF 方式寫入到檔案。這樣的話,新的 AOF 檔案就同時擁有了 2 種格式的資料。
當需要使用混合檔案進行恢複時,會先判斷 AOF 檔案的頭部是否為 RDB 格式,是的話,先使用 RDB 的方式加載資料,接着再處理後面的 AOF 資料。
這樣的話就能加快資料的恢複速度,又降低了資料丢失的風險。
當然, 這種混合方式會使得 AOF 檔案變得複雜,可讀性差,而且得是 4.0 版本以上才能使用。
總結
Redis 的持久化都有它的特點,那我們應該選擇哪種機制呢?
- 如果我們的資料允許丢失,那應該關閉持久化方式,這樣性能會很好。
- 如果我們希望能盡量的保證資料的安全性,那我們應該選擇混合持久化方式。
- 如果我們希望保證資料不丢失,那應該選擇 appendfsync 為 always,隻是這種對性能影響很大,是以一般都會直接考慮 mysql 了。