1、Redis數據持久化的必要性 由於redis是基於記憶體的資料庫,面臨數據掉電易失的風險,要避免數據丟失,最好將記憶體數據持久化到磁碟等永久存儲介質上。服務重啟時,會先載入磁碟文件內的數據到記憶體,完成數據恢復。 2、RDB(RedisDB) 對記憶體中的redis全量數據進行 時點快照 並序列化,以文 ...
1、Redis數據持久化的必要性
由於redis是基於記憶體的資料庫,面臨數據掉電易失的風險,要避免數據丟失,最好將記憶體數據持久化到磁碟等永久存儲介質上。服務重啟時,會先載入磁碟文件內的數據到記憶體,完成數據恢復。
2、RDB(RedisDB)
對記憶體中的redis全量數據進行時點快照並序列化,以文件形式保存到磁碟上,生成的是dump.rdb二進位文件。到了dump時間點就生成一份新的rdb文件,同時覆蓋掉舊的。服務重啟時直接將dump文件反序列化並載入到記憶體中,數據恢復速度較快,也是redis預設的持久化方式。hdfs的nameNode也是用類似的方式生成fsimage文件來做持久化的,hdfs的nameNode也是用類似的方式生成fsimage文件來做持久化的
執行方式:
阻塞式:
類似JVM的stop-the-world,做快照的時候不能處理客戶端請求,客戶端可以使用save命令觸發。優點原理簡單,能保證數據一致性,缺點是對用戶不友好。
非阻塞式:
服務端做數據快照的時候,可以繼續處理客戶端的請求,客戶端可以使用bgsave命令觸發。優點是對客戶端友好,但複雜度高,必須解決做快照的同時,併發寫操作造成的數據不一致問題。
redis中的所有key和value是分為兩個部分單獨存儲的,兩個數據區之間建立映射關係,數據修改只是映射關係的改變。
大體機制:當服務端接收到bgsave命令後,服務端不會立馬執行快照操作,而是選擇合適的時機fork一個子進程,這個子進程全量繼承父進程的key數據集和映射關係。實現類cow的效果,子進程只保證dump時點當前的數據一致性,至於併發修改的數據就交給下一次dump來持久化。
配置策略:
可以通過客戶端發命令的方式,也可以寫在配置文件中實現自動持久化。
save 900 1 //如果在900秒內發生了超過1次k-v更新就觸發一次dump
save 300 10 //如果在300秒內發生了超過10次k-v更新就觸發一次dump
save 60 10000 //如果在60秒內發生了超過1萬次k-v更新就觸發一次dump
dbfilename dump.rdb //快照文件名
dir /opt/redis/rep //快照存儲路徑
【每完成一次快照後,時間計和更新計數器都會清零】
優點:
- 全量備份,可以做到針對不同時間點的多版本恢復(此時需要避免覆蓋問題,推薦用多伺服器來存儲dump文件)。
- 備份文件緊湊單一,利於網路傳輸,適合災難恢復。
- 恢復大數據集速度比AOF快。
缺點:
- 最後一次快照時如果掉電,併發寫的數據將丟失,所以適合存儲能容忍這種風險的場合。
- fork過程會造成毫秒級的耗時,會造成短暫的拒絕相應。
3、AOF(AppendOnlyFile)
實時記錄每一條寫數據的命令,形成binlog,服務重啟時會原樣執行一遍aof文件中的所有命令,達到數據恢復的目的,但恢復速度比rdb式慢。hdfs中提供了類似的方式,edit-log,只是預設時關閉的。
幾乎可以做到不丟失任何數據,也可以控制丟失一秒內的數據。
備份的數據量太大,不夠緊湊,io交互頻繁。
寫入機制:在現代操作系統中,程式執行write系統調用時,是先將數據寫到一個記憶體buffer中,等到buffer滿或者用戶執行fsync或fdatasync
指令時才會將buffer數據刷到disc上,所以未刷盤的數據存在掉電丟失風險。
落盤策略由appendfssync選項控制:
- always:服務端每接收一個更新指令都刷到磁碟,不會發生數據丟失,但是io太過頻繁效率很低。
- everysecond:每隔1秒鐘刷一次盤,有可能丟失一秒鐘的數據,效率適中。
- no:服務端不主動刷盤,數據何時落盤完全取決於操作系統,只有當buffer滿了才會刷盤,丟失數據量不確定,效率最高。
AOF重寫機制:
由於AOF文件時間長了會很大,可以通過分析文件內容,將多條命令合併為一條,將對同一個key的多次操作只保留最新的那一次。
AOF重寫過程
- fork一個子進程負責重寫AOF文件
- 子進程創建一個臨時文件來寫入AOF數據
- 父進程開闢一個記憶體緩衝區接收新的寫命令
- 子進程重寫完畢後,父進程會獲得一個信號,父進程將新收到的寫命令通過子進程寫入臨時文件
- 用臨時文件替換掉舊的AOF文件
AOF重寫的觸發
- 手動式:通過客戶端發送bgrewriteaof命令。
- 自動式:必須在配置文件中配置如下兩個參數
- auto-aof-rewrite-min-size 500mb //只有當aof文件大於等於500M時,伺服器才會重寫aof文件,避免過小文件的重寫問題。
- auto-aof-rewrite-min-percentage 60 //在滿足最小閾值的前提下,超過上一次重寫後生成的文件體積的60%時將觸發重寫,避免了無限迴圈重寫。(如果尚未做過重寫,就以啟動時的AOF文件體積作為對比基準,如果此值為0,則表示關閉自動重寫功能)。
優點:
- 預設每秒刷盤,性能好不阻塞服務,最多丟失一秒數據。
- 如果發生誤操作(flushall等),只要文件未被重寫,立即停止服務將,AOF文件最後的flushall命令刪除,然後重啟redis服務實現數據恢復。
缺點:
- 相同數據集,AOF比RDB大很多。
- 數據恢復速度比RDB慢。