Redis 持久化之RDB和AOF

半城楓葉半城雨丶發表於2020-10-30
Redis 有兩種持久化方案,RDB (Redis DataBase)和 AOF (Append Only File)
 

一:什麼是AOF ?

  AOF 全稱是Append Only File,是 redis 記錄執行指令的日誌檔案。
 

1. 工作原理

  將寫操作追加到檔案中,AOF 日誌是寫後日志,“寫後”的意思是 Redis 是先執行命令,把資料寫入記憶體後,然後才記日誌;裡面記錄的是指令執行的步驟,非常詳細,描繪出了資料的變化過程。
 

2. AOF相關引數配置

  引數配置在 redis.conf 檔案裡。
  • appendonly  no                                  # 預設是no 表示不開啟AOF機制,yes 代表開啟
  • appendfilename  "appendonly.aof"       # aof檔名,預設是"appendonly.aof"
  • appendfsync everysec                        #aof持久化策略的配置,下文會詳述
  • no-appendfsync-on-rewrite  no          #  是重寫機制的相關引數,下文會說明 
  • auto-aof-rewrite-percentage  100       #  是重寫機制的相關引數,下文會說明 
  • auto-aof-rewrite-min-size  64mb       #  是重寫機制的相關引數,下文會說明
  • aof-use-rdb-preamble  no                 # Redis從4.0開始就提出了一個混合使用 AOF 日誌和記憶體快照的開關

3. AOF持久化策略

  就是當資料被寫入記憶體後,如何再寫到檔案的策略(為什麼要寫入檔案,因為不持久化,redis掛了後,記憶體的資料沒了,資料就丟了)
 
  關於持久化同步時間節點上的控制有三個引數選項:
    appendfsync always           表示不執行同步,由作業系統自己選擇時間保證資料同步到磁碟,速度最快;
    appendfsync everysec          表示每一秒執行一次同步,可能會導致丟失這1s資料
    appendfsync no             表示每次寫入記憶體後都執行同步,以保證資料同步到磁碟;
 
           

 

4. AOF的重寫機制

  很顯然,因為AOF檔案需要記錄每一步的操作步驟,所以檔案的冗餘內容會越來越多。所以聰明的 Redis 新增了重寫機制。當AOF檔案的大小超過所設定的閾值時,Redis就會對AOF檔案的內容壓縮。
 
  重寫的原理:Redis 會fork出一條新程式,讀取當前記憶體中的資料,並重新寫到一個臨時檔案中,這裡沒有讀取舊檔案(你都那麼大了,我還去讀你???),最後替換舊的aof檔案。AOF 檔案是以追加的方式,逐一記錄接收到的寫命令的。當一個鍵值對被多條寫命令反覆修改時,AOF 檔案會記錄相應的多條命令。但是在重寫的時候,是根據這個鍵值對當前的最新狀態,為它生成對應的寫入命令。這樣一來,一個鍵值對在重寫的新日誌中只用一條命令就行了,而且,在日誌恢復時,只用執行這條命令,就可以直接完成這個鍵值對的寫入了。所以新的AOF檔案大小會大大縮小。
 
  重寫觸發機制:當AOF檔案大小是上次rewrite後大小的一倍且檔案大於64M時觸發。這裡的“一倍”和“64M” 可以通過配置檔案修改。
  • auto-aof-rewrite-percentage 100
  預設值為100。aof自動重寫配置,當目前aof檔案大小超過上一次重寫的aof檔案大小的百分之多少進行重寫,即當aof檔案增長到一定大小的時候,Redis能夠呼叫bgrewriteaof對日誌檔案進行重寫,100代表大於一倍。
  • auto-aof-rewrite-min-size 64mb
  設定允許重寫的最小aof檔案大小,避免了達到約定百分比但尺寸仍然很小的情況還要重寫,意思就是至少達到64mb,才重寫
 
當redis當機重啟後,會讀取 "appendonly.aof" 檔案,將資料刷回到記憶體中去。
 

二:什麼是RDB ?

  這裡解釋為記憶體快照,就是指記憶體中的資料在某個時刻的狀態記錄。

1.  工作原理

  RDB 是 Redis 預設的持久化方案。在指定的時間間隔內,執行指定次數的寫操作,則會將記憶體中的資料寫入到磁碟中。即在指定目錄下生成一個dump.rdb檔案。Redis 重啟會通過載入dump.rdb檔案恢復資料。與上述的aof相比,aof是持續的疊加寫入,而RDB是整體寫入,相當於給記憶體的資料拍下了一張張照片。

2.  AOF相關引數配置

  引數配置在 redis.conf 檔案裡。 

  • # save:這裡是用來配置觸發 Redis的持久化條件,也就是什麼時候將記憶體中的資料儲存到硬碟。預設如下配置
    save 900 1 #表示900 秒內如果至少有 1 個 key 的值變化,則儲存
    save 300 10 #表示300 秒內如果至少有 10 個 key 的值變化,則儲存
    save 60 10000 #表示60 秒內如果至少有 10000 個 key 的值變化,則儲存
     
  • # 預設值為yes。當啟用了RDB且最後一次後臺儲存資料失敗,Redis是否停止接收資料。這會讓使用者意識到資料沒有正確持久化到磁碟上,否則沒有人會注意到災難(disaster)發生了。如果Redis重啟了,那麼又可以重新開始接收資料了
    stop-writes-on-bgsave-error yes
     
  • # 預設值是yes。對於儲存到磁碟中的快照,可以設定是否進行壓縮儲存。如果是的話,redis會採用LZF演算法進行壓縮。如果你不想消耗CPU來進行壓縮的話,可以設定為關閉此功能,但是儲存在磁碟上的快照會比較大。
    rdbcompression yes
     
  • # 預設值是yes。在儲存快照後,我們還可以讓redis使用CRC64演算法來進行資料校驗,但是這樣做會增加大約10%的效能消耗,如果希望獲取到最大的效能提升,可以關閉此功能。
    rdbchecksum yes 
     
  • # 設定快照的檔名,預設是 dump.rdb
    dbfilename dump.rdb
     
  • # 設定快照檔案的存放路徑,這個配置項一定是個目錄,而不能是檔名。使用上面的 dbfilename 作為儲存的檔名。
    dir /usr/local/var/db/redis/

 3. RDB的優缺點

優點:
  適合大規模的資料恢復,如果業務對資料完整性和一致性要求不高,RDB是很好的選擇。

缺點:
    資料的完整性和一致性不高,因為RDB可能在最後一次備份時當機了。
   

 三:總結

  1.  Redis 預設開啟RDB持久化方式,在指定的時間間隔內,執行指定次數的寫操作,則將記憶體中的資料寫入到磁碟中。
  2.  RDB 持久化適合大規模的資料恢復但它的資料一致性和完整性較差。
  3.  Redis 需要手動開啟AOF持久化方式,預設是每秒將寫操作日誌追加到AOF檔案中。
  4.  AOF 的資料完整性比RDB高,但記錄內容多了,會影響資料恢復的效率。
  5.  Redis 針對 AOF檔案大的問題,提供重寫的瘦身機制。
  6.  若只打算用Redis 做快取,可以關閉持久化。
  7.  若打算使用Redis 的持久化。建議RDB和AOF都開啟。其實RDB更適合做資料的備份,留一後手。AOF出問題了,還有RDB。

  優化建議:

     1. 資料不能丟失時,記憶體快照和 AOF 的混合使用是一個很好的選擇;
   2. 如果允許分鐘級別的資料丟失,可以只使用 RDB;
   3. 如果只用 AOF,優先使用 everysec 的配置選項,因為它在可靠性和效能之間取了一個平衡。

 

相關文章