Redis 持久化機制簡介【Redis 系列之三】
〇、前言
Redis 持久化主要有兩種:RDB(數據快照模式)、AOF(追加模式),另外就是這兩種模式的混合模式用。
本文將對這三種情況進行詳細介紹。
博主 Redis 相關文章都在這里了:http://www.rzrgm.cn/hnzhengfy/category/2229717.html
一、RDB(數據快照模式)
1.1 簡介
RDB(Redis Database Snapshot 快照)是 Redis 數據持久化的一種方式,又稱為 Snapshot,默認情況下 Redis 在指定的時間間隔內將內存中的數據集快照寫入磁盤,存放在副本文件中。當 Redis 重啟后又自動讀取到內存中。
- 工作原理
創建子進程:在執行 RDB 快照時,Redis 會調用 fork 函數創建一個子進程,盡管Redis本身是單線程運行的。這個子進程與父進程共享內存空間,但擁有獨立的地址空間。
寫入數據:子進程遍歷數據庫中的每個鍵值對,并將其序列化后寫入到一個新的 RDB 文件中。在這個過程中,主進程仍然可以處理客戶端的請求,不會受到磁盤寫入操作的影響。
替換原有文件:當子進程完成寫入操作后,它會用新生成的 RDB 文件替換掉原有的 RDB 文件,從而完成一次完整的快照過程。
關于 fork(),它是 Unix 和類 Unix 操作系統(如 Linux)中的一個關鍵系統調用,用于創建一個新的進程,這個新進程是原進程的副本,稱為子進程。原進程則被稱為父進程。fork() 的主要作用是在程序中實現并行處理和任務分解。
- 為什么需要使用 fork 函數來創建子進程?
避免阻塞主線程:Redis 的主要任務是處理客戶端請求。如果直接在主線程中生成 RDB 文件,那么在生成過程中,主線程將無法處理其他客戶端請求,這會導致服務暫時不可用。通過 fork() 創建一個子進程來執行這個耗時的操作,可以確保主線程繼續響應客戶端請求。
保證數據一致性:fork() 創建的子進程會繼承父進程的數據段(包括內存中的鍵值對)。這意味著,在子進程開始生成 RDB 文件的那一刻,它所看到的數據是一個完整的、一致的快照。這樣即使在生成 RDB 文件的過程中有新的寫操作發生,也不會影響到正在生成的 RDB 文件內容。
fork() 生成的子進程擁有與父進程相同的內存映像,但是它是只讀的。也就是說,子進程和父進程共享同一塊物理內存,直到其中一方嘗試修改這塊內存的內容(這被稱為“寫時復制”,Copy-On-Write)。即當父進程或子進程試圖修改某一塊內存時,操作系統會為該塊內存分配一個新的副本,只有在這個時候才會實際復制數據。因此,在生成RDB文件的過程中,除非有大量寫操作發生,否則父子進程之間實際上不需要進行大量的內存復制,從而提高了效率。
如下示意圖:

- RDB 模式的優勢
高性能:由于使用了 fork() 創建的子進程,主進程不會被磁盤寫入操作阻塞,從而保持了 Redis 的高性能。
適合大規模數據恢復:RDB 文件是一個緊湊的二進制文件,包含了當前數據庫中所有的鍵值對數據和對應的過期時間。當需要恢復數據時,Redis 可以直接從 RDB 文件加載數據,而不需要重新執行所有的寫操作,從而實現快速恢復。
空間效率高:相對于 AOF(Append-Only File)持久化來說,RDB 文件占用更少的磁盤空間,易于傳輸和存儲。
- RDB 模式的劣勢
數據丟失風險:持久化的數據可能會出現丟失的情況。因為在持久化進行過程中,或者在未到觸發備份的節點但已有數據發生變更,這時服務器突然宕機,存儲的數據可能并不完整。
Fork 耗時問題:如果數據集很大,Fork 可能會很耗時,并且如果 CPU 性能不好的話,可能會導致 Redis 在幾毫秒甚至一秒鐘內停止為客戶端提供服務。
配置項復雜性增加:需要仔細配置觸發快照的條件(例如,在多少秒內有多少鍵發生變化),以平衡性能和數據安全的需求。錯誤的配置可能導致過多或過少的快照生成,影響系統性能或數據安全性。
1.2 觸發方式一:自動觸發
- 配置觸發
在Redis的配置文件中,可以通過設置save m n參數來指定在多長時間內數據集存在多少次修改時自動觸發RDB快照。
例如,save 900 1表示在 900 秒內至少有 1 個鍵被修改時觸發 RDB 快照。
其他相關的配置項:
stop-writes-on-bgsave-error:默認情況下,如果 RDB 快照過程中出現錯誤,Redis 會繼續接受寫操作。可以通過設置該選項為 yes,讓 Redis 在 RDB 快照出錯時停止寫操作,以避免數據丟失。
rdbchecksum:默認開啟,表示在存儲快照后,Redis 使用 CRC64 算法來進行數據校驗。這個操作會增加一定的性能消耗,如果希望獲取最大的性能提升,可以關閉此功能。
rdbcompression:用于配置是否對磁盤中的快照文件進行壓縮存儲。如果是的話,Redis 會采用 LZF 算法進行壓縮,可以減少磁盤空間的占用,但會消耗一定的 CPU 性能。如果不希望消耗 CPU 性能來進行壓縮,可以設置為 no 關閉此功能。
dbfilename:用于生成的快照文件的名字,默認為 dump.rdb。
dir:配置生成的快照文件存儲的位置,默認為當前目錄下。
- 主從復制觸發
在主從復制過程中,如果從節點執行全量復制操作,主節點會自動執行 bgsave 命令,來生成 RDB 文件并發送給從節點。
- 執行特定命令觸發
執行 debug reload 命令重新加載 Redis 時,也會自動觸發 save 操作。
- 關閉 Redis 觸發
默認情況下,執行 shutdown 命令時,如果沒有開啟 AOF 持久化功能,則自動執行 bgsave。
1.3 觸發方式二:手動觸發
- save 命令
執行該命令會阻塞當前 Redis 服務,直到 RDB 快照生成完成為止。
這種方式在數據量大的時候可能會造成長時間阻塞,因此不建議在生產環境中使用。
示例命令:redis-cli save。
- bgsave 命令
Redis 主進程會 fork 一個子進程來處理 RDB 快照生成任務,而主進程可以繼續處理其他命令請求,即“寫時復制”(Copy-On-Write)。
這種方式對主進程性能影響較小,但 fork 操作本身可能會有一定的性能開銷。
示例命令:redis-cli bgsave。
執行上述命令后,Redis 會返回“Background saving started”的消息,表示 RDB 快照正在生成中。當快照生成完成后,Redis 會返回“OK”消息,并更新相關的統計信息。
二、AOF(追加模式)
2.1 簡介
Redis 的 AOF(Append Only File)持久化策略,通過記錄服務器接收到的每個 set、del 等操作命令到日志文件中,當 Redis 重啟時,它會重新執行這些命令來恢復數據。
- 工作原理
命令追加:Redis 服務器在執行寫命令時,會將命令以協議格式追加到 AOF 緩沖區中。這些命令包括 SET、DEL 等對數據庫進行修改的操作,而讀操作不會被記錄。
寫入文件:AOF 緩沖區中的數據會被周期性地寫入磁盤文件中的 AOF 文件。寫入的頻率可以通過配置文件中的 appendfsync 參數來設置,該參數決定了何時將緩沖區內容同步到磁盤上。
重寫機制:隨著時間的推移,AOF 文件可能會變得非常大,為了減小文件大小和提高恢復速度,Redis 提供了 AOF 文件重寫功能。重寫過程會創建一個新的 AOF 文件,將當前內存中的數據以命令序列的方式寫入新文件,然后替換原有的 AOF 文件。重寫過程中不包含對已過期或已被刪除數據的寫命令,因此可以顯著減少 AOF 文件的大小。

注意:AOF 新文件,也是在 disk 磁盤上的。
- 配置選項
appendfsync:這個參數用于設置 AOF 持久化的同步策略,它有三個可選值:
- always:每次寫操作后同步(數據零丟失,性能最低)。這種策略確保了最高的數據安全性,但會對性能產生較大影響,因為它需要在每次寫操作后都等待磁盤寫入完成。
- everysec:每秒同步一次(默認策略)。這是最常用的策略,它在性能和數據安全性之間取得了較好的平衡。Redis 每秒將 AOF 緩沖區的內容寫入磁盤一次,這樣即使在發生故障時,最多只會丟失最近一秒的數據。
- no:由操作系統決定同步時機。這種策略效率最高,但對數據安全性的影響也最大。在這種模式下,Redis 不會主動進行磁盤同步操作,而是依賴操作系統的文件緩存機制來決定何時將數據寫入磁盤。
auto-aof-rewrite-percentage:用于設置觸發 AOF 重寫的增長百分比。例如,如果將其設置為 100%,則表示當 AOF 文件的大小比上次重寫后增長了 100% 時,就會觸發 AOF 重寫。
auto-aof-rewrite-min-size:用于設置觸發 AOF 重寫的最小文件大小。只有當 AOF 文件達到這個指定的大小以上時,才會考慮是否觸發重寫。
注意:auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 這兩個配置項需要同時滿足才會觸發 AOF(Append Only File)重寫操作。
- AOF 模式的優勢
數據安全性高:相較于 RDB,AOF 提供更高的數據安全性,尤其是在頻繁更新的場景下。由于AOF是以追加方式記錄操作日志,因此即使在崩潰后也能最大限度地恢復數據。即使中途服務器宕機,或者 AOF 文件出現了寫入錯誤或者損壞,也可以通過 redis-check-aof 工具解決數據一致性問題,或者通過 redis-check-rdb 工具來從 AOF 文件中恢復 RDB 文件。
可讀性好:AOF文件是一個文本文件,可以通過簡單的文本編輯工具查看和修改,更加友好和可讀。
支持秒級同步:根據配置文件中的 appendfsync 選項,有三種同步策略:always、everysec 和 no,可以按需靈活配置。
通過 redis-check-aof 工具來解決數據一致性問題的簡單步驟:
- 備份原始AOF文件。避免修復過程中出現問題,破壞原始文件的狀態,造成額外的損失。
- 檢查 AOF 文件的損壞情況。工具會輸出檢查結果,顯示文件中存在的錯誤類型、錯誤位置以及可能的修復建議。
- 修復 AOF 文件。根據檢查結果選擇合適的修復方法:如果AOF文件的錯誤較少且簡單,可以嘗試手動修復;對于更復雜的錯誤,可能需要使用專業的文本編輯工具或腳本進行處理。也可以使用 redis-check-aof 工具自動修復。執行帶有 --fix 選項的 redis-check-aof 命令,工具會自動嘗試修復文件中的錯誤。但需要注意,自動修復可能會導致一些數據丟失或不一致的情況。
- 驗證修復后的 AOF 文件。啟動 Redis 服務器并加載修復后的文件,確認數據能夠正常加載。然后再檢查數據完整性,可以通過執行一些查詢操作或與備份數據進行比較,來驗證修復后的AOF文件中的數據是否與預期一致。如果發現數據仍然存在問題,可能需要重新檢查和修復AOF文件。
- AOF 模式的劣勢
文件體積較大:由于 AOF 記錄的是每一個寫命令,所以其文件大小通常比 RDB 大很多。不過,Redis 支持 AOF 重寫(rewrite),可以壓縮 AOF 文件大小。
恢復速度較慢:與 RDB 相比,從 AOF 文件恢復數據的速度要慢一些,因為它需要重新執行所有的命令。
性能開銷較高:AOF 持久化需要對每個寫命令進行同步操作,而 RDB 持久化只需要定期執行快照操作。特別是在“always”同步策略下,AOF 持久化會顯著降低 Redis 的吞吐量。
2.2 觸發方式一:自動觸發
自動觸發依賴配置參數,當滿足特定條件時,Redis 會自動執行 AOF 重寫。
自動觸發就是依賴 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 這兩個配置項的值。
當兩個配置項同時滿足時,自動觸發。
簡單示例:
# 當 AOF 日志大小至少為 64mb,并且增長超過了上次重寫后的 100% 時,觸發 AOF 重寫
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
2.3 觸發方式二:手動觸發
手動觸發允許用戶通過 Redis 命令主動執行 AOF 文件的重寫操作。
使用bgrewriteaof命令手動觸發 AOF 重寫。
- 大概工作流程
Fork 子進程:Redis 主進程會通過 fork() 創建一個子進程。
子進程生成新 AOF 文件:子進程基于當前內存數據生成一個新的緊湊 AOF 文件(臨時文件)。
主進程處理新寫入命令:在子進程生成新 AOF 文件期間,主進程繼續處理客戶端請求,并將新寫入的命令暫存到 AOF 重寫緩沖區(aof_rewrite_buf)。
合并數據:子進程完成新 AOF 文件后,主進程將重寫緩沖區中的新命令追加到新文件中。
替換舊文件:新 AOF 文件生成后,替換舊的 AOF 文件,完成重寫。
# 手動觸發 AOF 重寫
redis-cli BGREWRITEAOF
# 查看重寫進度(可選)
redis-cli INFO persistence
三、混合模式(RDB + AOF)
3.1 簡介
Redis 4.0 引入:允許在 AOF 重寫時,將內存數據以 RDB 快照的形式寫入 AOF 文件的開頭,后面追加增量的 AOF 命令。
混合模式目的就是,結合 RDB 的快速恢復和 AOF 的數據完整性,使兩者優勢互補,以達到最佳效果。
- 工作原理
AOF 重寫觸發:當滿足 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size 條件時,生成混合 AOF 文件:
- RDB 快照部分:子進程將當前內存數據以 RDB 格式寫入新文件的開頭(aof-preamble)。
- AOF 增量部分:將重寫期間的新寫命令以 AOF 格式追加到文件末尾。
文件替換:新文件(如 appendonly.aof_tmp)原子替換舊的 AOF 文件。
- 數據恢復大致流程
加載 RDB 快照:快速恢復到重寫時的內存狀態。
重放 AOF 增量:應用新寫入的命令,確保數據一致性。
例如,在一個數據庫備份恢復的場景中,先加載RDB獲取大部分數據,再通過AOF恢復近期的修改,確保數據的完整性。
- 混合模式的優勢
恢復速度快:RDB 快照提供快速恢復基礎,AOF 增量補全數據。
數據安全性高:AOF 記錄所有寫操作,減少數據丟失風險。
文件體積優化:RDB 部分壓縮了冗余命令。
- 混合模式的劣勢
文件結構復雜:混合文件需同時支持 RDB 和 AOF 格式解析。
磁盤空間需求:可能比純 AOF 占用更多空間。
混合模式與兩個單獨模式的對比:
| 特性 | 純 RDB | 純 AOF | 混合模式 |
| 恢復速度 | 快(二進制) | 慢(逐行解析) | 快(RDB 基礎 + AOF 增量) |
| 數據丟失風險 | 快照間隔內可能丟失數據 | 根據同步策略(如 1 秒內) | 最小化丟失(AOF 保障) |
| 文件體積 | 小 | 大 | 中(RDB 壓縮 + AOF 增量) |
| 適用場景 | 數據量小,對恢復速度要求高 | 數據量大,需高安全性 | 需平衡速度與數據完整性 |
3.2 配置方法
總共涉及四個配置項,如下:
# 啟用 AOF:
appendonly yes
# 開啟混合持久化:
aof-use-rdb-preamble yes
# 配置 AOF 重寫條件:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
參考:https://blog.csdn.net/Seky_fei/article/details/106594029 https://tongyi.aliyun.com/qianwen/
本文來自博客園,作者:橙子家,歡迎微信掃碼關注博主【橙子家czzj】,有任何疑問歡迎溝通,共同成長!
轉載本文請注明原文鏈接:http://www.rzrgm.cn/hnzhengfy/p/18781020/redis3

浙公網安備 33010602011771號