redis(13)持久化操作-AOF

Silent丿丶黑羽發表於2023-03-02

AOF(Append Only File)

以日誌的形式來記錄每個寫操作(增量儲存),將 Redis 執行過的所有寫指令記錄下來 (讀操作不記錄), 只許追加檔案但不可以改寫檔案,redis 啟動之初會讀取該檔案重新構建資料,換言之,redis 重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作。
 

AOF 持久化流程

  1. 客戶端的請求寫命令會被 append 追加到 AOF 緩衝區內;

  2. AOF 緩衝區根據 AOF 持久化策略 [always,everysec,no] 將操作 sync 同步到磁碟的 AOF 檔案中;

  3. AOF 檔案大小超過重寫策略或手動重寫時,會對 AOF 檔案 rewrite 重寫,壓縮 AOF 檔案容量;

  4. Redis 服務重啟時,會重新 load 載入 AOF 檔案中的寫操作達到資料恢復的目的。

redis(13)持久化操作-AOF  

AOF 預設不開啟

可以在 redis.conf 中配置檔名稱預設為 appendonly.aof 檔案中開啟,AOF 檔案的儲存路徑,同 RDB 的路徑一致。
 

AOF 和 RDB 同時開啟,redis 聽誰的?

AOF 和 RDB 同時開啟,系統預設取 AOF 的資料(資料不會存在丟失)。
 

AOF 啟動、修復、恢復

  • AOF 的備份機制和效能雖然和 RDB 不同,但是備份和恢復的操作同 RDB 一樣,都是複製備份檔案,需要恢復時再複製到 Redis 工作目錄下,啟動系統即載入。

  • 正常恢復

    • 修改預設的 appendonly no,改為 yes。
    • 將有資料的 aof 檔案複製一份儲存到對應目錄 (檢視目錄:config get dir)。
    • 恢復:重啟 redis 然後重新載入。
  • 異常恢復

    • 修改預設的 appendonly no,改為 yes。
    • 如遇到 AOF 檔案損壞,透過 /usr/local/bin/ redis-check-aof–fix appendonly.aof 進行恢復。
    • 備份被寫壞的 AOF 檔案。
    • 恢復:重啟 redis,然後重新載入。
       

AOF 同步頻率設定

  • appendfsync always:始終同步,每次 Redis 的寫入都會立刻記入日誌;效能較差但資料完整性比較好。

  • appendfsync everysec:每秒同步,每秒記入日誌一次,如果當機,本秒的資料可能丟失。

  • appendfsync no:redis 不主動進行同步,把同步時機交給作業系統。
     

Rewrite 壓縮

AOF 採用檔案追加方式,檔案會越來越大為避免出現此種情況,新增了重寫機制,當 AOF 檔案的大小超過所設定的閾值時,Redis 就會啟動 AOF 檔案的內容壓縮,只保留可以恢復資料的最小指令集,可以使用命令 bgrewriteaof。
 

重寫原理,如何實現重寫

AOF 檔案持續增長而過大時,會 fork 出一條新程式來將檔案重寫 (也是先寫臨時檔案最後再 rename),redis4.0 版本後的重寫,是指把 rdb 的快照,以二進位制的形式附在新的 aof 頭部,作為已有的歷史資料,替換掉原來的流水賬操作。

no-appendfsync-on-rewrite:

  • 如果 no-appendfsync-on-rewrite=yes ,不寫入 aof 檔案只寫入快取,使用者請求不會阻塞,但是在這段時間如果當機會丟失這段時間的快取資料。(降低資料安全性,提高效能)

  • 如果 no-appendfsync-on-rewrite=no,還是會把資料往磁碟裡刷,但是遇到重寫操作,可能會發生阻塞。(資料安全,但是效能降低)
     

觸發機制,何時重寫

Redis 會記錄上次重寫時的 AOF 大小,預設配置是當 AOF 檔案大小是上次 rewrite 後大小的一倍且檔案大於 64M 時觸發。

重寫雖然可以節約大量磁碟空間,減少恢復時間。但是每次重寫還是有一定的負擔的,因此設定 Redis 要滿足一定條件才會進行重寫。

  • auto-aof-rewrite-percentage:設定重寫的基準值,檔案達到 100% 時開始重寫(檔案是原來重寫後檔案的 2 倍時觸發)。

  • auto-aof-rewrite-min-size:設定重寫的基準值,最小檔案 64MB。達到這個值開始重寫。

  • 系統載入時或者上次重寫完畢時,Redis 會記錄此時 AOF 大小,設為 base_size,

  • 如果 Redis 的 AOF 當前大小 >= base_size +base_size*100% (預設) 且當前大小 >=64mb (預設) 的情況下,Redis 會對 AOF 進行重寫。

  • 例如:檔案達到 70MB 開始重寫,降到 50MB,下次什麼時候開始重寫?100MB
     

重寫流程

  1. bgrewriteaof 觸發重寫,判斷是否當前有 bgsave 或 bgrewriteaof 在執行,如果有,則等待該命令結束後再繼續執行;

  2. 主程式 fork 出子程式執行重寫操作,保證主程式不會阻塞;

  3. 子程式遍歷 redis 記憶體中資料到臨時檔案,客戶端的寫請求同時寫入 aof_buf 緩衝區和 aof_rewrite_buf 重寫緩衝區,保證原 AOF 檔案完整以及新 AOF 檔案生成期間的新的資料修改動作不會丟失;

  4. 子程式寫完新的 AOF 檔案後,向主程式發訊號,父程式更新統計資訊。主程式把 aof_rewrite_buf 中的資料寫入到新的 AOF 檔案;

  5. 使用新的 AOF 檔案覆蓋舊的 AOF 檔案,完成 AOF 重寫。

redis(13)持久化操作-AOF  

AOF持久化優勢

redis(13)持久化操作-AOF

備份機制更穩健,丟失資料機率更低。

可讀的日誌文字,透過操作 AOF 穩健,可以處理誤操作。
 

AOF持久化劣勢

  • 比起 RDB 佔用更多的磁碟空間。

  • 恢復備份速度要慢。

  • 每次讀寫都同步的話,有一定的效能壓力。

  • 存在個別 Bug,造成恢復不能。
     

總結

redis(13)持久化操作-AOF

相關文章