【Redis】再看Redis持久化機制RDB和AOF

Redis作爲目前最流行的內存數據庫,持久化機制是我們必須要考慮的問題之一。這裏主要總結一下Redis的持久化機制以及他們之間的優缺點。
Redis持久機制主要分爲RDB和AOF。
RDB即熟稱快照方式(Redis Database),AOF即文件寫入方式(Append On File),下面分別介紹一下這兩種方式。

RDB

RDB:快照方式,redis可以設置每隔多長時間自動生成一份當前內存中所有數據的一份快照文件。rdb文件是經過壓縮的二進制文件。redis會用新的rdb文件替換舊的rdb文件,總是保存最新的一份rdb文件。

服務器在創建和載入rdb文件時主要通過SAVE命令和BGSAVE命令實現。

1、SAVE命令會阻塞Redis服務器進程,直到rdb文件創建完畢爲止,在阻塞期間,服務器不能處理任何命令請求。
2、BGSAVE命令 和SAVE命令不同,BGSAVE命令會通過fork()派生出一個子進程來負責創建RDB文件,服務器進程繼續處理命令請求。

子進程對當前內存中的數據進行持久化,並不會修改當前的數據結構,如果父進程收到了讀寫請求,那麼會把處理的那一部分數據複製一份到內存,對複製後的數據進行修改,所以即使對某個數據進行了修改,redis持久化到RDB中的數據也是未修改的數據,這也是把RDB文件稱爲"快照"文件的原因,子進程所看到的數據在它被創建的一瞬間就固定下來了,父進程修改的某個數據只是該數據的複製品。

優點:
1、冷備:RDB會生成多個數據文件,每個數據文件都代表了某一個時刻中redis的數據,這種多個數據文件的方式,非常適合做冷備,可以將這種完整的數據文件發送到一些遠程的安全存儲上去。
2、持久化保持Redis高性能:當進行RDB持久化時,對redis服務處理讀寫請求的影響非常小,可以讓redis保持高性能,因爲redis主進程只需要fork一個子進程,讓子進程執行磁盤IO操作來進行RDB持久化即可。生成一次RDB文件的過程就是把當前時刻內存中的數據一次性寫入文件中,而AOF則需要先把當前內存中的小量數據轉換爲操作指令,然後把指令寫到內存緩存中,然後再刷寫入磁盤。
3、重啓和恢復快:相對於AOF持久化機制來說,直接基於RDB數據文件來重啓和恢復redis的數據會更加快速。AOF,存放的是指令日誌,做數據恢復的時候,要回放和執行所有的指令日誌,從而恢復內存中的所有數據。而RDB,就是一份數據文件,恢復的時候,直接加載到內存中即可。

缺點:

1、數據丟失 :一般每隔幾分鐘執行一次,數據易丟失
2、RDB文件不易多大:否則客戶端程序會暫停幾秒,對redis性能有影響。

AOF

aof持久化是通過保存redis服務器所執行的寫命令來記錄數據庫狀態的。

redis服務器在執行完一個寫命令之後,會進行參數校驗,符合條件的會將執行的命令追加到服務器狀態的aof_buf緩衝區末尾,然後從緩衝區中再持久化到aof文件的末尾。可以通過設置appendfsync(always,everysec,no)參數的值來設定緩衝區向硬盤進行持久化的行爲,默認是everysec,每秒就要執行一次。

aof持久化造成的問題

1、AOF文件過大問題
由於aof文件中保存的是所有執行的寫命令,這樣會造成文件內容隨着時間流逝不斷的加大,文件體積也會越來越大,這樣會對redis服務器甚至整個宿主機造成影響,並且文件越大,還原時間也越長。

爲了解決這個問題,redis提供了AOF文件重寫。
通過該功能,redis服務器可以創建一個新的AOF文件來代替現有的AOF文件,新舊
兩個AOF文件保持的數據庫狀態一致,但新的文件不會保護任何浪費空間的冗餘命令,
所以新的文件比舊的文件體積會小很多。

2、AOF重寫問題
AOF重寫,redis將重寫程序放到子進程執行。這樣可以保證父進程繼續執行命令請求,同時使用進程而不是線程避免了鎖帶來的安全性問題。

但是AOF重寫時是直接讀取的redis的數據庫狀態,而不是從原有的aof文件進行數據讀取,命令在不斷的執行,會造成數據庫狀態和重寫aof文件數據不一致問題。

爲了解決數據一致性問題,redis設置了重寫緩衝區

在重寫期間,服務器進程需要執行三個工作:
1、執行客戶端發來的命令
2、將執行後的寫命令追加到AOF緩衝區
3、將執行後的寫命令追加到AOF重寫緩衝區。
當完成重寫工作後子進程會向父進程發送一個信號,這時父進程會調用函數將
aof重寫緩衝區的數據持久化到重寫aof文件中,之後原子的替換原有的aof文件。
處理信號函數時會阻塞進程。

優點:
1、更大程度數據不丟失:一般AOF會每隔1秒,通過一個後臺線程執行一次fsync操作,最多丟失1秒鐘的數據。
2、寫入性能高:AOF日誌文件以append-only模式寫入,所以沒有任何磁盤尋址的開銷,寫入性能非常高,而且文件不容易破損,即使文件尾部破損,也很容易修復。即使重寫,也不會影響客戶端操作。
3、可讀性高:適合做災難備份
缺點:
1、文件過大對於同一份數據來說,AOF日誌文件通常比RDB數據快照文件更大。
2、AOF的寫性能比RDB的寫性能低:因爲AOF一般會配置成每秒fsync一次日誌文件,當然,每秒一次fsync,性能也還是很高的,只不過比起RDB來說性能低,如果要保證一條數據都不丟,也是可以的,AOF的fsync設置成每寫入一條數據,fsync一次,但是這樣,redis的性能會大大下降。
3、基於AOF文件做恢復的速度不如基於RDB文件做恢復的速度:因爲aof文件需要一條一條執行命令,而rdb直接恢復數據庫狀態的二進制指令就可以。

總結:
可以使用RDB和AOF相結合的方式進行Redis持久化,但是可能要考慮兼容性的問題。

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