Redis詳解(七)------ AOF 持久化

  上一篇文章咱們介紹了Redis的RDB持久化,RDB 持久化存在一個缺點是必定時間內作一次備份,若是redis意外down掉的話,就會丟失最後一次快照後的全部修改(數據有丟失)。對於數據完整性要求很嚴格的需求,怎麼解決呢?html

  本篇博客接着來介紹Redis的另外一種持久化方式——AOF。redis

一、AOF簡介

  Redis的持久化方式之一RDB是經過保存數據庫中的鍵值對來記錄數據庫的狀態。而另外一種持久化方式 AOF 則是經過保存Redis服務器所執行的寫命令來記錄數據庫狀態。數據庫

  好比對於以下命令:安全

  

  RDB 持久化方式就是將 str1,str2,str3 這三個鍵值對保存到 RDB文件中,而 AOF 持久化則是將執行的 set,sadd,lpush 三個命令保存到 AOF 文件中。服務器

二、AOF 配置

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

  

  ①、appendonly:默認值爲no,也就是說redis 默認使用的是rdb方式持久化,若是想要開啓 AOF 持久化方式,須要將 appendonly 修改成 yes。函數

  ②、appendfilename :aof文件名,默認是"appendonly.aof"工具

  ③、appendfsync:aof持久化策略的配置;性能

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

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

      everysec表示每秒執行一次fsync,可能會致使丟失這1s數據。一般選擇 everysec ,兼顧安全性和效率。

  ④、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。

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

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

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

三、開啓 AOF

  將 redis.conf 的 appendonly 配置改成 yes 便可。

  AOF 保存文件的位置和 RDB 保存文件的位置同樣,都是經過 redis.conf 配置文件的 dir 配置:

  

  能夠經過 config get dir 命令獲取保存的路徑。

四、AOF 文件恢復

  重啓 Redis 以後就會進行 AOF 文件的載入。

  異常修復命令:redis-check-aof --fix 進行修復

五、 AOF 重寫

  因爲AOF持久化是Redis不斷將寫命令記錄到 AOF 文件中,隨着Redis不斷的進行,AOF 的文件會愈來愈大,文件越大,佔用服務器內存越大以及 AOF 恢復要求時間越長。爲了解決這個問題,Redis新增了重寫機制,當AOF文件的大小超過所設定的閾值時,Redis就會啓動AOF文件的內容壓縮,只保留能夠恢復數據的最小指令集。可使用命令 bgrewriteaof 來從新。

  好比對於以下命令:

  

  若是不進行 AOF 文件重寫,那麼 AOF 文件將保存四條 SADD 命令,若是使用AOF 重寫,那麼AOF 文件中將只會保留下面一條命令:

sadd animals "dog" "tiger" "panda" "lion" "cat"

  也就是說 AOF 文件重寫並非對原文件進行從新整理,而是直接讀取服務器現有的鍵值對,而後用一條命令去代替以前記錄這個鍵值對的多條命令,生成一個新的文件後去替換原來的 AOF 文件。

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

  這裏再提一下,咱們知道 Redis 是單線程工做,若是 重寫 AOF 須要比較長的時間,那麼在重寫 AOF 期間,Redis將長時間沒法處理其餘的命令,這顯然是不能忍受的。Redis爲了克服這個問題,解決辦法是將 AOF 重寫程序放到子程序中進行,這樣有兩個好處:

  ①、子進程進行 AOF 重寫期間,服務器進程(父進程)能夠繼續處理其餘命令。

  ②、子進程帶有父進程的數據副本,使用子進程而不是線程,能夠在避免使用鎖的狀況下,保證數據的安全性。

  使用子進程解決了上面的問題,可是新問題也產生了:由於子進程在進行 AOF 重寫期間,服務器進程依然在處理其它命令,這新的命令有可能也對數據庫進行了修改操做,使得當前數據庫狀態和重寫後的 AOF 文件狀態不一致。

  爲了解決這個數據狀態不一致的問題,Redis 服務器設置了一個 AOF 重寫緩衝區,這個緩衝區是在建立子進程後開始使用,當Redis服務器執行一個寫命令以後,就會將這個寫命令也發送到 AOF 重寫緩衝區。當子進程完成 AOF 重寫以後,就會給父進程發送一個信號,父進程接收此信號後,就會調用函數將 AOF 重寫緩衝區的內容都寫到新的 AOF 文件中。

  這樣將 AOF 重寫對服務器形成的影響降到了最低。

六、AOF的優缺點

  優勢:

  ①、AOF 持久化的方法提供了多種的同步頻率,即便使用默認的同步頻率每秒同步一次,Redis 最多也就丟失 1 秒的數據而已。

  ②、AOF 文件使用 Redis 命令追加的形式來構造,所以,即便 Redis 只能向 AOF 文件寫入命令的片段,使用 redis-check-aof 工具也很容易修正 AOF 文件。

  ③、AOF 文件的格式可讀性較強,這也爲使用者提供了更靈活的處理方式。例如,若是咱們不當心錯用了 FLUSHALL 命令,在重寫還沒進行時,咱們能夠手工將最後的 FLUSHALL 命令去掉,而後再使用 AOF 來恢復數據。

  缺點:

  ①、對於具備相同數據的的 Redis,AOF 文件一般會比 RDF 文件體積更大。

  ②、雖然 AOF 提供了多種同步的頻率,默認狀況下,每秒同步一次的頻率也具備較高的性能。但在 Redis 的負載較高時,RDB 比 AOF 具好更好的性能保證。

  ③、RDB 使用快照的形式來持久化整個 Redis 數據,而 AOF 只是將每次執行的命令追加到 AOF 文件中,所以從理論上說,RDB 比 AOF 方式更健壯。官方文檔也指出,AOF 的確也存在一些 BUG,這些 BUG 在 RDB 沒有存在。

   那麼對於 AOF 和 RDB 兩種持久化方式,咱們應該如何選擇呢?

  若是能夠忍受一小段時間內數據的丟失,毫無疑問使用 RDB 是最好的,定時生成 RDB 快照(snapshot)很是便於進行數據庫備份, 而且 RDB 恢復數據集的速度也要比 AOF 恢復的速度要快,並且使用 RDB 還能夠避免 AOF 一些隱藏的 bug;不然就使用 AOF 重寫。可是通常狀況下建議不要單獨使用某一種持久化機制,而是應該兩種一塊兒用,在這種狀況下,當redis重啓的時候會優先載入AOF文件來恢復原始的數據,由於在一般狀況下AOF文件保存的數據集要比RDB文件保存的數據集要完整。Redis後期官方可能都有將兩種持久化方式整合爲一種持久化模型。

相關文章
相關標籤/搜索