Redis是一個內存數據庫,數據保存在內存中。但我們都知道存儲在內存中的數據會因為外部因素而丟失,所以Redis會把數據持久化到磁盤中,至於是如何持久化呢?
一、RDB
1.手動觸發
- save:該命令會阻塞當前Redis服務器,執行save命令期間,Redis不能處理其他命令,直到RDB過程完成為止。
- bgsave:執行該命令時,Redis會在后台異步進行快照操作,快照同時還可以響應客戶端請求。具體操作是Redis進程執行fork操作創建子進程,RDB持久化過程由子進程負責,完成后自動結束。阻塞只發生在fork階段,一般時間很短。基本上 Redis 內部所有的RDB操作都是采用 bgsave 命令。
2.自動觸發
-
根據redis.conf配置里的save m n定時觸發(用的是BGSAVE)
-
主從復制時,主節點自動觸發
-
執行Debug Relaod
-
執行Shutdown且沒有開啟AOF持久化
# 在幾秒內改動了多少數據就觸發持久化 # 想禁用的話不設置save 或者save "" save 900 1 save 300 10 save 60 10000 # 備份進程出錯主進程停止寫入操作 stop-writes-on-bgsave-error yes # 是否壓縮rdb文件 推薦no 相對於硬盤成本cpu更值錢 rdbcompression yes
3.優缺點
優點:
- 只會生成一個文件,方便操作,文件小
- 相對AOF來說,恢復大數據集的速度快
- 在RDB持久化開始時,只會fork一個子線程處理所有的持久化工作,不會影響到父系線程
缺點:
- 如果你想保證數據的高可用性,即最大限度的避免數據丟失,那么RDB將不是一個很好的選擇。因為系統一旦在定時持久化之前出現宕機現象,此前沒有來得及寫入磁盤的數據都將丟失。
- 由於RDB是通過fork子進程來協助完成數據持久化工作的,因此,如果當數據集較大時,可能會導致整個服務器停止服務幾百毫秒,甚至是1秒鍾。
二、AOF
全量備份總是耗時的,有時候我們提供一種更加高效的方式AOF,工作機制很簡單,redis會將每一個收到的寫命令都通過write函數追加到文件中。通俗的理解就是日志記錄。
-
記錄除了查詢以外的所有變更數據庫狀態的指令
-
以append的形式追加保存到AOF文件中(增量)
-
日志重寫解決AOF文件不斷增大的問題,原理如下
-
調用fork,創建一個子進程
-
子進程把新的AOF寫到一個臨時文件里,不依賴原來的AOF文件
-
主進程持續將新的變動同時寫到內存和原來的AOF里
-
主進程獲取子進程重寫AOF完成信號,往新AOF同步增量變動
-
使用新的AOF文件替換掉舊的AOF文件
-
# 默認關閉若要開啟將no改為yes appendonly no # append文件的名字 appendfilename "appendonly.aof" # AOF文件的寫入方式 # always一旦緩存區內容發生變化就寫入AOF文件中 appendfsync always # everysec 每個一秒將緩存區內容寫入文件 默認開啟的寫入方式 appendfsync everysec # 將寫入文件的操作交由操作系統決定 appendfsync no # 當AOF文件大小的增長率大於該配置項時自動開啟重寫(這里指超過原大小的100%)。 auto-aof-rewrite-percentage 100 # 當AOF文件大小大於該配置項時自動開啟重寫 auto-aof-rewrite-min-size 64mb
優點:
- AOF可以更好的保護數據不丟失,一般AOF會每隔1秒,通過一個后台線程執行一次fsync操作,最多丟失1秒鍾的數據。
- AOF日志文件沒有任何磁盤尋址的開銷,寫入性能非常高,文件不容易破損。
- AOF日志文件即使過大的時候,出現后台重寫操作,也不會影響客戶端的讀寫。
- AOF日志文件的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。
缺點:
- AOF日志文件相對於RDB來說會更大
- AOF開啟后,支持的寫QPS會比RDB支持的寫QPS低
通過對比可以看出單獨使用AOF和RDB都存在不少都問題,所以在redis4.0之后,帶來了新的持久化選項——混合持久化。
三、RDB-AOF混合持久化
如果開啟了混合持久化,aof在重寫時,不再是單純將內存數據轉換為RESP命令寫入aof文件,而是將重寫這一刻之前的內存做rdb快照處理,並且將rdb快照內容和增量的aof修改內存數據的命令存在一起,都寫入新的aof文件,新的aof文件一開始不叫appendonly.aof,等到重寫完成后,新的aof文件才會進行改名,原子的覆蓋原有的aof文件,完成新舊兩個aof文件的替換。
於是在redis重啟的時候,可以先加載rdb文件,然后再重放增量的aof日志就可以完全替代之前的aof全量文件重放,因此重啟效率大幅得到提高。
於是在redis重啟的時候,可以先加載rdb文件,然后再重放增量的aof日志就可以完全替代之前的aof全量文件重放,因此重啟效率大幅得到提高。
簡單說就是BGSAVE做鏡像全量持久化,AOF做增量持久化。
注:圖來自網絡
如果redis沒有升級到4.0,優先選擇 RDB 還是 AOF 呢?
分析對比兩種方式並做了測試后,發現這是兩種不同風格的持久化方式。那么應該如何選擇呢?
- 對於企業級的中大型應用,如果不想犧牲數據完整性但是又希望保持高效率,那么你應該同時使用 RDB 和 AOF 兩種方式。
- 如果你不打算耗費精力在這個地方,只需要保證數據完整性,那么優先考慮使用 AOF 方式。
- RDB 方式非常適合大規模的數據恢復,如果業務對數據完整性和一致性要求不高,RDB 是很好的選擇。
