淺談redis持久化

今晚打老虎嗎發表於2019-05-04

前言

前面我們講了 Redis 的資料結構(Redis那些事之資料結構),今天我們來看看 Redis 的持久化,Redis 的持久化分兩種 RDB 和 AOF。這兩種各有優缺點,我們先看下官方是怎麼描述這兩種結構的:

RDB永續性以指定的時間間隔執行資料集的時間點快照。
AOF永續性記錄伺服器接收的每個寫入操作,將在伺服器啟動時再次播放,重建原始資料集。 使用與Redis協議本身相同的格式以僅追加方式記錄命令。 當Redis太大時,Redis能夠重寫日誌背景。

我們可以選擇關閉持久化,把 Redis 作為一個記憶體快取使用,也可以開啟持久化做資料庫使用,RDB 和 AOF 可以同時開啟,同時開啟的情況下 Redis 優先讀取 AOF 裡面的資料。最重要的是理解 RDB 和 AOF 的區別和各自的優缺點,以便我們在不同的業務員場景下擇優選擇。

RDB

RDB 持久化可以手動執行,也可以根據配置選項定期執行,該功能可以將某個時間點的資料庫狀態儲存到一個 RDB 檔案中。因為 RDB 是儲存在硬碟中,所以即使 Redis 伺服器程式掛掉,只要 RDB 檔案存在,Redis 就可以用它來還原資料狀態。
Redis 提供兩個手動執行命令 SAVE、BGSVE,SAVE命令執行時,客戶端傳送的所以命令請求都會被阻塞。BGSAVE 命令是由主程式 fork 出一個子程式進行持久化。所以在持久化的過程中 Redis 還可以繼續執行客戶端的命令,持久化由子程式執行。因為 BGSAVE 命令是非阻塞的,所以自動執行全部採用的是 BGSAVE 命令。
RDB 檔案儲存了使用者的寫入和刪除命令,並根據不同的資料型別進行相應的編碼,一個標準的 RDB 檔案一般有一下部分組成:

  1. REDIS
  2. db_version RDB 檔案版本號
  3. database 資料庫
  4. EOF 結束識別符號
  5. check_sum 校驗和

其中 database 的格式為:

  1. SELECTDB 類似 flag 標識,當程式讀到這兒的時候標識接下來讀入的是一個資料庫號碼
  2. db_number 資料庫號
  3. key_value_pairs 儲存了資料庫中所以的鍵值對資料、過期條件等

其中 key_value_pairs 部分的 key 是採用的 SDS 編碼, value 是根據不同的資料型別進行儲存(參考:Redis那些事之資料結構

AOF

除了 RDB 持久化功能之外 Redis 還提供了 AOF(append only file)持久化功能,AOF 是通過儲存 Redis伺服器所執行的寫命令來記錄資料庫狀態的。
AOF 的實現可以功能大體分為 命令追加(append)、檔案寫入、檔案同步(sync)。
當 AOF 功能開啟的時候,伺服器在執行完一個寫命令後,會以寫一個是將被執行命令追加到伺服器狀態的 aof_buf 緩衝區的末尾。Redis 伺服器在一個事件迴圈(loop)週期裡它會呼叫一次 flushAppendOnlyFile 函式。考慮是否將 aof_buf 緩衝區中的內容寫入和儲存到 AOF 檔案裡面。
因為 AOF 是通過客戶端傳送的寫命令來保證資料庫的狀態的,所以隨著時間的流失, AOF 檔案中的內容可能會出現越來越多對同樣一個鍵的修改。檔案的體積也越來越大,如不加以控制,可能會對 Redis 伺服器造成影響,使用 AOF 恢復所需的時間也會加大。 Redis 為此提供了 AOF 重寫功能, AOF 的重寫並不是對現有檔案進行分析然後進行重寫,而是遍歷讀取資料庫裡的資料,然後把對應的命令轉成寫入命令,寫入到一個新的檔案。這個執行過程同樣是阻塞進行的,所以可以繼續採用子程式來執行,等子程式處理完後對父程式傳送一個訊號通知重新執行完畢。然後父程式對原來的 AOF 檔案原子性的覆蓋。(在子程式執行重寫的過程,父程式同樣會接收命令,這個期間主程式所接收到的命令都會儲存到緩衝區,在執行覆蓋前,Redis服務會把緩衝區的命令追加到子程式發來的 AOF 檔案裡面)。

RDB 和 AOF 的優缺點

RDB 的優點

  • RDB 檔案非常適合備份,比如可以根據時間或者是修改的次數,進行歸檔,然後在發生災難的時候輕鬆的根據恢復不同的版本資料。
  • RDB 非常適合災難恢復,可以將單個壓縮檔案傳輸到遠端資料中心,也可以傳輸到 Amazon S3(可能是加密的)。
  • RDB 最大限度地提高了 Redis 的效能,因為 Redis 父程式為了持久化需要做的唯一工作就是分配一個將完成所有其餘工作的孩子。 父例項永遠不會執行磁碟 I/O 或類似操作。
  • 與 AOF 相比,RDB 允許使用大資料集更快地重啟。

AOF 的優點

  • 使用 AOF Redis 更持久:你可以使用不同的 fsync 策略:根本沒有 fsync,每秒 fsync,每次查詢都有 fsync。使用 fsync 的預設策略,每秒寫入效能仍然很好(使用後臺執行緒執行 fsync,並且當沒有 fsync 正在進行時,主執行緒將努力執行寫入。)但是你只能丟失一秒的寫入。
  • AOF 日誌是僅附加日誌,因此如果停電,則沒有搜尋,也沒有損壞問題。即使由於某種原因(磁碟已滿或其他原因)日誌以半寫命令結束,redis-check-aof 工具也能夠輕鬆修復它。
  • 當 Redis 太大時,Redis 能夠在後臺自動重寫 AOF。重寫是完全安全的,因為當 Redis 繼續附加到舊檔案時,使用建立當前資料集所需的最小操作集生成一個全新的檔案,並且一旦第二個檔案準備就緒,Redis 會切換兩個並開始附加到新的那一個。
  • AOF 以易於理解和解析的格式一個接一個地包含所有操作的日誌。你甚至可以輕鬆匯出 AOF 檔案。例如,即使你使用 FLUSHALL 命令重新整理了所有錯誤,如果在此期間未執行重寫日誌,你仍然可以儲存資料集,只需停止伺服器,刪除最新命令,然後重新啟動 Redis。

RDB 的缺點

  • 如果你需要在 Redis 掛掉後將資料的丟失性降到最小,那麼 RDB 可能不合適。你可以根據配置檔案設定不同的時間儲存點,例如;對資料集進行至少 5 分鐘和100次寫入之後儲存 RDB 檔案,那麼 5 分鐘內或者修改次數不滿足 100 次的資料可能就會丟失。
  • RDB 為了持久化會經常 fork 才能將子程式的資料持久儲存在磁碟上,如果資料集很大, fork 可能會非常耗時,並且如果資料集非常大且 CPU 效能不佳,可能會導致 Redis 停止服務客戶端幾毫秒甚至一秒鐘。 AOF 也需要 fork ,但你可以調整你想要重寫日誌的頻率而不需要對永續性進行任何權衡。

AOF 的缺點

  • 因為 AOF 是儲存的寫入命令,所以同樣資料下 AOF 一般比 RDB 檔案更大。
  • 根據確切的 fsync 策略,AOF 可能比 RDB 慢。一般來說,fsync 設定為每秒效能仍然非常高,並且在 fsync 禁用的情況下,即使在高負載下也應該與 RDB 一樣快。即使在寫入負載很大的情況下,RDB 仍能夠提供有關最大延遲的更多保證。

相關文章