1 minute read

Redis 提供了兩種不同的持久化方法將數據存在硬碟

RDB (Redis Database) 持久化

將某一時刻或指定時間的資料進行快照 (snapshot) 寫成一份 .rdb 檔案到硬碟中,當 Redis 要重啟時會來讀取這份檔案的內容來使用。

快照 (snapshot)

快照執行的方法有以下兩種指令:

  • SAVE: 當接收到 SAVE 指令的 Redis 就不會響應其他請求,需要等到快照操作完成才能繼續接收其他響應。
  • BGSAVE: Redis 會調用 fork 來創建一個子進程。由子進程開始將資料集寫入臨時 RDB 檔案,當子進程寫完新的 RDB 檔案後,它會取代舊的 RDB 檔案。

配置範例

除了以上兩種指令,也可以自己設置 save 的配置選項:

# redis.conf

save 60 100   #當60秒內有100次寫入時,Redis 自動觸發 BGSAVE 指令
save 10 1000  #當10秒內有1000次寫入時,Redis 自動觸發 BGSAVE 指令

配置文件中的 save 指令實際上會觸發 BGSAVE 操作,這是 Redis 的設計決定,旨在確保在自動保存數據的過程中,服務的高效性和可用性不會受到影響。這樣的設計讓 Redis 能夠在不中斷服務的情況下,定期保存數據,確保數據的持久性。

AOF (Append Only File) 持久化

AOF 是 Redis 的一種持久化機制,通過將每個寫操作記錄到一個日誌文件中來實現數據的持久化。這與 RDB(Redis Database)快照不同,RDB 是定期保存數據的快照,而 AOF 是通過追加寫操作記錄來保持數據的完整性。

AOF 持久化可以通過配置 appenonly yes 來打開。 而 appendfsync 則有三種選項:

  1. always: 每個寫入指令都要同步到硬碟中,這樣做會導致嚴重降低 Redis 的速度
  2. everysec: 每秒執行一次同步,如果系統崩潰時,則會丟失最後一秒的資料
  3. no: 讓操作系統來決定什麼時候要同步,這是最有風險的一種配置,系統崩潰時這種配置會導致 Redis 遺失不定量的數據,不推薦使用

重寫/壓縮 AOF 文件

雖然 AOF 持久化提供了多種的配置來滿足資料寫入的要求,但也有一個缺陷就是 AOF 的文件體積不斷變大, 像是重複的指令會讓 .aof 文件快速的體積變大。

為了解決 AOF 文件體積不斷增大的問題,我們可以經由設置 BGREWRITEAOF 這個指令會通過移除文件中冗餘的指令進行重寫 AOF 文件。

BGREWRITEAOF 和 BGSAVE 這個指令的工作原理非常相似,會建立一個子進程對 AOF 文件進行重寫,因此在快照 BGSAVE 創建子進程遇到的效能問題, AOF 重寫也會遇到。

AOF 重寫機制

  • 父進程:當計劃進行 AOF 重寫時,父進程會開啟一個新的增量 AOF 文件來繼續記錄新的寫操作
  • 子進程:子進程負責將當前內存中的數據集寫入到新的基礎 AOF 文件中。生成的新 AOF 文件包含了移除冗餘寫操作後的數據
  • 臨時清單文件:Redis 使用臨時清單文件來追蹤新的基礎 AOF 文件和增量 AOF 文件
  • 原子替換操作:當基礎 AOF 文件和增量 AOF 文件都準備好後,Redis 會執行原子替換操作,將臨時清單文件替換為當前使用的 AOF 文件

配置範例

以下是 Redis 配置文件中的相關設置,用於控制 AOF 重寫行為:

# redis.conf

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# 當 AOF 文件體積大於 64 MB 且體積比上一次重寫後的體積大了 100% 時,Redis 將進行重寫

如果 AOF 重寫過於頻繁,可以調整 auto-aof-rewrite-percentage 設置為大於 100 的值,以減少重寫的頻率,但需要考慮這樣可能會增加數據恢復的時間。

總結

優點

特性 RDB (Redis Database) AOF (Append Only File)
恢復速度 RDB 文件是一個二進制格式的快照,讀取速度快 AOF 記錄每個寫操作,能最大程度地確保數據不丟失
性能 快照生成是在子進程中進行,不會阻塞主進程 通過配置 appendfsync 可以選擇性能和數據安全性的平衡點
文件體積 定期快照,硬碟占用較小 可以選擇不同的同步策略來優化性能

缺點

特性 RDB (Redis Database) AOF (Append Only File)
數據丟失風險 在兩次快照之間的數據可能會丟失 文件體積較大,需要定期重寫以減少體積
重寫頻繁時的效能問題 頻繁的 BGSAVE 操作可能影響性能 由於需要重放所有的寫操作來恢復數據,恢復速度較慢

參考資料

Redis persistence
Redis 實戰

Tags:

Categories:

Updated: