Redis詳解(四)----持久化之AOF

AOF持久化介紹

       Redis的持久化的另一種方式AOF,全稱是append only file,以日誌的形式來記錄每個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),
只許追加文件但不可以改寫文件,redis啓動之初會讀取該文件重新構建數據,換言之,Redis重啓的話就根據日誌文件的內容將寫指令從前到後執行一次以完成數據的恢復工作。

注意:如果RDB和AOF兩種方式都打開的話,Redis會優先使用AOF的方式。

AOF 配置

  在 redis.conf 配置文件的 APPEND ONLY MODE 下:

1、appendonly:默認是關閉的,也就是說redis 默認使用的是rdb方式持久化,如果想要開啓 AOF 持久化方式,需要將 appendonly 修改爲 yes。

2、appendfilename :aof文件名,默認是"appendonly.aof"

3、appendfsync:aof持久化策略的配置,有3種;

     

 always表示每次寫入都執行fsync,以保證數據同步到磁盤,效率很低;

 everysec表示每秒執行一次fsync,如果一秒內出現宕機,可能會導致丟失這1s數據。通常選擇 everysec ,兼顧安全性和效率。

    no表示不執行fsync,由操作系統保證數據同步到磁盤,速度最快,但是不太安全;

4、no-appendfsync-on-rewrite:在aof重寫或者寫入rdb文件的時候,會執行大量IO,此時對於everysec和always的aof模式來說,執行fsync會造成阻塞過長時間,no-appendfsync-on-rewrite字段設置爲默認設置爲no。如果對延遲要求很高的應用,這個字段可以設置爲yes,否則還是設置爲no,這樣對持久化特性來說這是更安全的選擇。   設置爲yes表示rewrite期間對新寫操作不fsync,暫時存在內存中,等rewrite完成後再寫入,默認爲no,建議yes。Linux的默認fsync策略是30秒。可能丟失30秒數據。默認值爲no。

5、auto-aof-rewrite-percentage:默認值爲100。aof自動重寫配置,當目前aof文件大小超過上一次重寫的aof文件大小的百分之多少進行重寫,即當aof文件增長到一定大小的時候,Redis能夠調用bgrewriteaof對日誌文件進行重寫。當前AOF文件大小是上次日誌重寫得到AOF文件大小的二倍(設置爲100)時,自動啓動新的日誌重寫過程。

6、auto-aof-rewrite-min-size:64mb。設置允許重寫的最小aof文件大小,避免了達到約定百分比但尺寸仍然很小的情況還要重寫。

7、aof-load-truncated:aof文件可能在尾部是不完整的,當redis啓動的時候,aof文件的數據被載入內存。重啓可能發生在redis所在的主機操作系統宕機後,尤其在ext4文件系統沒有加上data=ordered選項,出現這種現象  redis宕機或者異常終止不會造成尾部不完整現象,可以選擇讓redis退出,或者導入儘可能多的數據。如果選擇的是yes,當截斷的aof文件被導入的時候,會自動發佈一個log給客戶端然後load。如果是no,用戶必須手動redis-check-aof修復AOF文件纔可以。默認值爲 yes。

AOF 恢復/修復

  正常恢復:將有數據的aof文件複製一份保存到對應目錄(config get dir),重啓 Redis 之後就會進行 AOF 文件的載入。

  異常修復:redis-check-aof --fix appendonly.aof 進行修復

AOF 重寫

  由於AOF持久化是Redis不斷將寫命令記錄到 AOF 文件中,AOF 的文件會越來越大,佔用服務器內存越大以及 AOF 恢復要求時間越長。爲了解決這個問題,Redis新增了重寫機制,當AOF文件的大小超過所設定的閾值時,Redis就會啓動AOF文件的內容壓縮,只保留可以恢復數據的最小指令集。可以向 Redis 發送 BGREWRITEAOF 命令,這個命令會移除 AOF 文件中冗餘的命令來重寫 AOF 文件,使 AOF 文件的體積變得儘可能地小。實際上aof文件重寫並不需要對現有的aof文件進行任何讀取、分析或者寫入操作,這個功能是根據通過讀取服務器當前數據庫狀態實現的。

aof重寫命令會進行大量寫的操作,所以調用這個函數的線程會被長時間阻塞,而redis是單線程處理命令請求,如果由服務器直接調用這個函數的話,在aof重寫期間,服務器將無法處理客戶端請求,所以就把aof重寫放到子進程中執行。

但是在子進程進行aof重寫期間,服務器進程還需要繼續處理命令請求,而新的命令可能會修改數據庫狀態,使當前數據庫狀態與重寫後的aof文件保存的數據庫狀態不一致。

爲了解決這個問題,redis服務器設置了一個aof重寫緩衝區,這個緩衝區在服務器創建子進程後開始使用,當redis執行一個寫命令後,服務器同樣會把這個命令發送給aof緩衝區和aof重寫緩衝區。aof緩衝區的內容會定期被寫入和同步到aof文件,對現有的aof文件處理照常進行;重創建子進程開始,服務器執行所有寫的命令都會被記錄到aof重寫緩衝區。

aof重寫完成後,會向父進程發送一個信號父進程接收到該信號後,會將aof重寫緩衝區中的內容寫入新aof文件中,此時新aof文件中保存的數據庫狀態就與服務器狀態一致了,對新aof文件改名,覆蓋現有的aof文件,完成新舊aof文件替換。

   AOF 文件重寫觸發機制:通過 redis.conf 配置文件中的 auto-aof-rewrite-percentage:默認值爲100,以及auto-aof-rewrite-min-size:64mb 配置,也就是說默認Redis會記錄上次重寫時的AOF大小,默認配置是當AOF文件大小是上次rewrite後大小的一倍且文件大於64M時觸發。

優缺點:

優點

  • 安全性相對RDB方式高很多。
  • AOF文件是一個只進行追加的日誌文件,所以不需要寫入seek,即使由於某些原因(磁盤空間已滿,寫的過程中宕機等等)未執行完整的寫入命令,你也也可使用redis-check-aof工具修復這些問題。
  • AOF 文件的格式可讀性較強,這也爲使用者提供了更靈活的處理方式。例如,如果我們不小心錯用了 FLUSHALL 命令,在重寫還沒進行時,我們可以手工將最後的 FLUSHALL 命令去掉,然後再使用 AOF 來恢復數據。

缺點

  • 對於相同的數據集來說,AOF 文件的體積通常要大於 RDB 文件的體積。
  • 效率相對RDB方式低很多。
  • 根據所使用的 fsync 策略,AOF 的速度可能會慢於 RDB 。 在一般情況下, 每秒 fsync 的性能依然非常高, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快, 即使在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間(latency)。

如何選擇使用哪種持久化方式?

一般來說, 如果想達到足以媲美 PostgreSQL 的數據安全性, 你應該同時使用兩種持久化功能。

如果你非常關心你的數據, 但仍然可以承受數分鐘以內的數據丟失, 那麼你可以只使用 RDB 持久化。

有很多用戶都只使用 AOF 持久化, 但我們並不推薦這種方式: 因爲定時生成 RDB 快照(snapshot)非常便於進行數據庫備份, 並且 RDB 恢復數據集的速度也要比 AOF 恢復的速度要快, 除此之外, 使用 RDB 還可以避免之前提到的 AOF 程序的 bug 。

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