Redis實戰和核心原理詳解(9)RDB和AOF的優缺點對比以及如何選擇

一、RDB的優缺點

1.1、RDB的優點

(1)RDB文件是緊湊的二進制文件,比較適合做冷備,全量複製的場景。

  • RDB做會生成多個文件,每個文件都代表了某一個時刻的Redis完整的數據快照;
  • RDB這種多個數據文件的方式,非常適合做冷備,因爲大量的一個個的文件,可以每隔一定的時間,複製出來;
  • 可以將這種完整的數據文件發送到一些遠程的雲服務、分佈式存儲上進行安全的存儲,以預定好的備份策略來定期備份Redis中的數據;
  • AOF也可以做冷備,只有一個文件,但是你可以寫個腳本,每隔一定時間,去copy一份這個文件出來,相對比較麻煩,不推薦;

問題:RDB做冷備,優勢在哪兒呢?

由Redis去控制固定時長生成快照文件的事情,比較方便;

  • AOF,還需要自己寫一些腳本去做這個事情,各種定時;
  • RDB數據做冷備,在最壞的情況下,提供數據恢復的時候,速度比AOF快;

(2)相對於AOF持久化機制來說,直接基於RDB數據文件來重啓和恢復Redis進程,更加快速;

問題:爲什麼恢復的時候RDB比AOF快?

  • AOF,存放的指令日誌,做數據恢復的時候,其實是要回放和執行所有的指令日誌,來恢復出來內存中的所有數據的;
  • RDB,就是一份數據文件,恢復的時候,直接加載到內存中即可;
  • RDB的時候,Redis主進程只需要fork一個子進程,讓子進程執行磁盤IO操作來進行RDB持久化即可;

(3)RDB對Redis對外提供的讀寫服務,影響非常小,可以讓Redis保持高性能,因爲Redis主進程只需要fork一個子進程,讓子進程執行磁盤IO操作來進行RDB持久化即可;

  • RDB每次寫,都是直接寫Redis內存,只是在一定的時候,纔會將數據寫入磁盤中;
  • AOF,每次都是要寫文件的,雖然可以快速寫入os cache中,但是還是有一定的時間開銷的,速度肯定比RDB略慢一些;

(4)RDB使用單獨子進程來進行持久化,主進程不會進行任何IO操作,保證了Redis的高性能 ;

1.2、RDB的缺點

(1)如果想要在Redis故障時,儘可能少的丟失數據,那麼RDB沒有AOF好。

一般來說,RDB數據快照文件,都是每隔5分鐘,或者更長時間生成一次,這個時候就得接受一旦Redis進程宕機,那麼會丟失最近5分鐘的數據;

這個問題,也是RDB最大的缺點,就是不適合做第一優先的恢復方案,如果你依賴RDB做第一優先恢復方案,會導致數據丟失的比較多;

(2)RDB每次在fork子進程來執行RDB快照數據文件生成的時候,如果數據文件特別大,可能會導致對客戶端提供的服務暫停數毫秒,或者甚至數秒;

一般不要讓RDB的間隔太長,否則每次生成的RDB文件太大了,對Redis本身的性能可能會有影響的;

(3)RDB無法實現實時或者秒級持久化

RDB是間隔一段時間進行持久化,如果持久化之間Redis發生故障,會發生數據丟失。

二、AOF的優缺點

2.1、AOF的優點

(1)AOF可以更好的保護數據不丟失。

一般AOF會每隔1秒,通過一個後臺線程執行一次fsync操作,最多丟失1秒鐘的數據,Redis進程掛了,最多丟掉1秒鐘的數據;

(2)AOF日誌文件以append-only模式寫入,寫入性能比較高

AOF日誌文件以append-only模式寫入,所以沒有任何磁盤尋址的開銷,寫入性能非常高,而且文件不容易破損,即使文件尾部破損,也很容易修;

(3)AOF日誌文件即使過大的時候,出現後臺重寫操作,也不會影響客戶端的讀寫。

因爲在rewrite log的時候,會對其中的指令進行壓縮,創建出一份需要恢復數據的最小日誌出來。再創建新日誌文件的時候,老的日誌文件還是照常寫入。

當新的merge後的日誌文件ready的時候,再交換新老日誌文件即可。

(4)適合做災難性的誤刪除緊急恢復

AOF日誌文件的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。比如某人不小心用flushall命令清空了所有數據,只要這個時候後臺rewrite還沒有發生,那麼就可以立即拷貝AOF文件,將最後一條flushall命令給刪了,然後再將該AOF文件放回去,就可以通過恢復機制,自動恢復所有數據;

2.2、AOF的缺點

(1)對於同一份數據來說,AOF日誌文件通常比RDB數據快照文件更大,恢復速度慢;

我們可以簡單的認爲AOF就是日誌文件,此文件只會記錄“變更操作”(例如:set/del等),如果server中持續的大量變更操作,將會導致AOF文件非常的龐大,意味着server失效後,數據恢復的過程將會很長;

事實上,一條數據經過多次變更,將會產生多條AOF記錄,其實只要保存當前的狀態,歷史的操作記錄是可以拋棄的;因爲AOF持久化模式還伴生了“AOF rewrite”。

(2)AOF開啓後,支持的寫QPS會比RDB支持的寫QPS低,因爲AOF一般會配置成每秒fsync一次日誌文件,當然,每秒一次fsync,性能也還是很高的;

如果你要保證一條數據都不丟,也是可以的,AOF的fsync設置成沒寫入一條數據,fsync一次,那就完蛋了,Redis的QPS大降;

(3)以前AOF發生過bug,就是通過AOF記錄的日誌,進行數據恢復的時候,沒有恢復一模一樣的數據出來

所以說,類似AOF這種較爲複雜的基於命令日誌/merge/回放的方式,比基於RDB每次持久化一份完整的數據快照文件的方式,更加脆弱一些,容易有bug。不過AOF就是爲了避免rewrite過程導致的bug,因此每次rewrite並不是基於舊的指令日誌進行merge的,而是基於當時內存中的數據進行指令的重新構建,這樣健壯性會好很多。

三、RDB和AOF到底該如何選擇

1、不要僅僅使用RDB,因爲那樣會導致你丟失很多數據;

2、也不要僅僅使用AOF,因爲那樣有兩個問題:

  • 你通過AOF做冷備,沒有RDB做冷備,恢復速度更快;
  • 第二,RDB每次簡單粗暴生成數據快照,更加健壯,可以避免AOF這種複雜的備份和恢復機制的bug;

3、綜合使用AOF和RDB兩種持久化機制,用AOF來保證數據不丟失,作爲數據恢復的第一選擇;

用RDB來做不同程度的冷備,在AOF文件都丟失或損壞不可用的時候,還可以使用RDB來進行快速的數據恢復;


參考文章:

1、Redis in Action - [美] Josiah L.Carlsono
2、https://blog.csdn.net/johnstrive/article/details/78423595
3、https://blog.csdn.net/qq_34190023/article/details/82715705

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章