Redis 持久化機制: RDB & AOF
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 則有三種選項:
- always: 每個寫入指令都要同步到硬碟中,這樣做會導致嚴重降低 Redis 的速度
- everysec: 每秒執行一次同步,如果系統崩潰時,則會丟失最後一秒的資料
- 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 操作可能影響性能 | 由於需要重放所有的寫操作來恢復數據,恢復速度較慢 |