Redis 有兩種持久化方案,RDB (Redis DataBase)和 AOF (Append Only File)
一:什麼是AOF ?
AOF 全稱是Append Only File,是 redis 記錄執行指令的日誌檔案。
1. 工作原理
將寫操作追加到檔案中,AOF 日誌是寫後日志,“寫後”的意思是 Redis 是先執行命令,把資料寫入記憶體後,然後才記日誌;裡面記錄的是指令執行的步驟,非常詳細,描繪出了資料的變化過程。
2. AOF相關引數配置
引數配置在 redis.conf 檔案裡。
- appendonly no # 預設是no 表示不開啟AOF機制,yes 代表開啟
- appendfilename "appendonly.aof" # aof檔名,預設是"appendonly.aof"
- appendfsync everysec #aof持久化策略的配置,下文會詳述
-
no-appendfsync-on-rewrite no # 是重寫機制的相關引數,下文會說明
-
auto-aof-rewrite-percentage 100 # 是重寫機制的相關引數,下文會說明
-
auto-aof-rewrite-min-size 64mb # 是重寫機制的相關引數,下文會說明
- aof-use-rdb-preamble no # Redis從4.0開始就提出了一個混合使用 AOF 日誌和記憶體快照的開關
3. AOF持久化策略
就是當資料被寫入記憶體後,如何再寫到檔案的策略(為什麼要寫入檔案,因為不持久化,redis掛了後,記憶體的資料沒了,資料就丟了)
關於持久化同步時間節點上的控制有三個引數選項:
appendfsync always 表示不執行同步,由作業系統自己選擇時間保證資料同步到磁碟,速度最快;
appendfsync everysec 表示每一秒執行一次同步,可能會導致丟失這1s資料
appendfsync no 表示每次寫入記憶體後都執行同步,以保證資料同步到磁碟;
4. AOF的重寫機制
很顯然,因為AOF檔案需要記錄每一步的操作步驟,所以檔案的冗餘內容會越來越多。所以聰明的 Redis 新增了重寫機制。當AOF檔案的大小超過所設定的閾值時,Redis就會對AOF檔案的內容壓縮。
重寫的原理:Redis 會fork出一條新程式,讀取當前記憶體中的資料,並重新寫到一個臨時檔案中,這裡沒有讀取舊檔案(你都那麼大了,我還去讀你???),最後替換舊的aof檔案。AOF 檔案是以追加的方式,逐一記錄接收到的寫命令的。當一個鍵值對被多條寫命令反覆修改時,AOF 檔案會記錄相應的多條命令。但是在重寫的時候,是根據這個鍵值對當前的最新狀態,為它生成對應的寫入命令。這樣一來,一個鍵值對在重寫的新日誌中只用一條命令就行了,而且,在日誌恢復時,只用執行這條命令,就可以直接完成這個鍵值對的寫入了。所以新的AOF檔案大小會大大縮小。
重寫觸發機制:當AOF檔案大小是上次rewrite後大小的一倍且檔案大於64M時觸發。這裡的“一倍”和“64M” 可以通過配置檔案修改。
- auto-aof-rewrite-percentage 100
預設值為100。aof自動重寫配置,當目前aof檔案大小超過上一次重寫的aof檔案大小的百分之多少進行重寫,即當aof檔案增長到一定大小的時候,Redis能夠呼叫bgrewriteaof對日誌檔案進行重寫,100代表大於一倍。
- auto-aof-rewrite-min-size 64mb
設定允許重寫的最小aof檔案大小,避免了達到約定百分比但尺寸仍然很小的情況還要重寫,意思就是至少達到64mb,才重寫
當redis當機重啟後,會讀取 "appendonly.aof" 檔案,將資料刷回到記憶體中去。
二:什麼是RDB ?
這裡解釋為記憶體快照,就是指記憶體中的資料在某個時刻的狀態記錄。
1. 工作原理
RDB 是 Redis 預設的持久化方案。在指定的時間間隔內,執行指定次數的寫操作,則會將記憶體中的資料寫入到磁碟中。即在指定目錄下生成一個dump.rdb檔案。Redis 重啟會通過載入dump.rdb檔案恢復資料。與上述的aof相比,aof是持續的疊加寫入,而RDB是整體寫入,相當於給記憶體的資料拍下了一張張照片。
2. AOF相關引數配置
引數配置在 redis.conf 檔案裡。
- # save:這裡是用來配置觸發 Redis的持久化條件,也就是什麼時候將記憶體中的資料儲存到硬碟。預設如下配置
save 900 1 #表示900 秒內如果至少有 1 個 key 的值變化,則儲存save 300 10 #表示300 秒內如果至少有 10 個 key 的值變化,則儲存save 60 10000 #表示60 秒內如果至少有 10000 個 key 的值變化,則儲存
-
# 預設值為yes。當啟用了RDB且最後一次後臺儲存資料失敗,Redis是否停止接收資料。這會讓使用者意識到資料沒有正確持久化到磁碟上,否則沒有人會注意到災難(disaster)發生了。如果Redis重啟了,那麼又可以重新開始接收資料了stop-writes-on-bgsave-error yes
-
# 預設值是yes。對於儲存到磁碟中的快照,可以設定是否進行壓縮儲存。如果是的話,redis會採用LZF演算法進行壓縮。如果你不想消耗CPU來進行壓縮的話,可以設定為關閉此功能,但是儲存在磁碟上的快照會比較大。rdbcompression yes
-
# 預設值是yes。在儲存快照後,我們還可以讓redis使用CRC64演算法來進行資料校驗,但是這樣做會增加大約10%的效能消耗,如果希望獲取到最大的效能提升,可以關閉此功能。rdbchecksum yes
-
# 設定快照的檔名,預設是 dump.rdbdbfilename dump.rdb
-
# 設定快照檔案的存放路徑,這個配置項一定是個目錄,而不能是檔名。使用上面的 dbfilename 作為儲存的檔名。dir /usr/local/var/db/redis/
3. RDB的優缺點
優點:
適合大規模的資料恢復,如果業務對資料完整性和一致性要求不高,RDB是很好的選擇。
缺點:
資料的完整性和一致性不高,因為RDB可能在最後一次備份時當機了。
三:總結
- Redis 預設開啟RDB持久化方式,在指定的時間間隔內,執行指定次數的寫操作,則將記憶體中的資料寫入到磁碟中。
- RDB 持久化適合大規模的資料恢復但它的資料一致性和完整性較差。
- Redis 需要手動開啟AOF持久化方式,預設是每秒將寫操作日誌追加到AOF檔案中。
- AOF 的資料完整性比RDB高,但記錄內容多了,會影響資料恢復的效率。
- Redis 針對 AOF檔案大的問題,提供重寫的瘦身機制。
- 若只打算用Redis 做快取,可以關閉持久化。
- 若打算使用Redis 的持久化。建議RDB和AOF都開啟。其實RDB更適合做資料的備份,留一後手。AOF出問題了,還有RDB。
優化建議:
1. 資料不能丟失時,記憶體快照和 AOF 的混合使用是一個很好的選擇;
2. 如果允許分鐘級別的資料丟失,可以只使用 RDB;
3. 如果只用 AOF,優先使用 everysec 的配置選項,因為它在可靠性和效能之間取了一個平衡。