本文為您介紹redis的持久化機制以及持久化的選型。
目錄
持久化策略
RDB(RedisDatabase)快照
AOF(Append Only File)
混合持久化策略
RDB與AOF對比
持久化策略使用建議
Redis數據備份策略建議
補充知識
save與bgsave對比
bgsave的寫時復制(COW)機制
持久化策略
Redis提供了很多跟數據持久化相關的配置,大體上,可以組成以下幾種策略:
- 無持久化:完全關閉數據持久化,不保證數據安全。相當于將Redis完全當做緩存。
- RDB(RedisDatabase)快照:按照一定的時間間隔緩存Redis所有數據快照。
- AOF(Append Only File):記錄Redis收到的每一次寫操作。這樣可以通過操作重演的方式恢Redis的數據。
- RDB+AOF:同時保存Redis的數據和操作。
更多內容,請參見https://redis.io/docs/latest/operate/oss_and_stack/management/persistence/
RDB(RedisDatabase)快照
- 定義:RDB可以在指定的時間間隔,備份當前時間點的內存中的全部數據集,并保存到餐盤文件當中。在恢復時,再將磁盤中的快照文件直接都會到內存里。
- 特點:RDB存的是全量數據,你甚至可以直接用RDB來傳遞數據。例如如果需要從一個Redis服務中將數據同步到另一個Redis服務(最好是同版本),就可以直接復制最近的RDB文件。
- 儲存位置:通常是dump.rdb文件。
- 觸發時機:
- 滿足配置文件中默認的快照配置時,會自動觸發RDB快照。
- 手動執行save或者bgsave指令時,會觸發RDB快照。
- 其中save方法會在備份期間阻塞主線程。
- bgsve則不會阻塞主線程。但是他會fork一個子線程進行持久化,這個過程中會要將數據復制一份,因此會占用更多內存和CPU。
- 主從復制時會觸發RDB備份。
LASTSAVE指令查看最后一次成功執行快照的時間。時間是一個代表毫秒的LONG數字,在linux中可以使用date -d @{timestamp} 快速格式化。
- 核心配置參數
這些配置直接影響 RDB 持久化的安全性、性能和存儲效率,實際配置時需根據業務對數據一致性的要求、服務器資源(CPU / 磁盤)情況綜合權衡。配置參數 含義 默認值 配置建議 dir 指定 RDB 文件和 AOF 文件的存儲目錄 無默認值,需手動配置 建議設置為獨立的持久化目錄,如 /var/lib/redis
dbfilename 指定 RDB 快照文件的名稱 dump.rdb 保持默認即可,如需區分不同實例可修改,如 dump-6379.rdb
rdbcompression 是否啟用 RDB 文件壓縮(使用 LZF 算法) yes 1. 建議保持默認 yes
,節省磁盤空間
2. 若 CPU 資源緊張且磁盤充足,可設為no
提升性能stop-writes-on-bgsave-error 當 bgsave 快照寫入失敗時,是否停止接受新的寫入請求stop-writes-oin-bgsave-error 。 yes 1. 生產環境建議保持默認 yes
,避免數據不一致
2. 若有其他數據一致性保障機制,可設為no
rdbchecksum 是否對 RDB 文件啟用 CRC64 校驗 yes 1. 建議保持默認 yes
,確保數據完整性
2. 若追求極致性能且能接受一定數據風險,可設為no
(約提升 10% 性能)
AOF(Append Only File)
- 定義:以日志的形式記錄每個寫操作(讀操作不記錄)。
- 特點:只允許追加文件而不允許改寫文件。
- 觸發時機:每次寫操作后。
- 核心參數配置
配置參數 含義 默認值 配置建議 appendonly 是否開啟 AOF 持久化功能 no 1. 需持久化時設為 yes
2. 與 RDB 配合使用時建議開啟appendfilename 指定 AOF 文件的名稱 appendonly.aof 保持默認即可,多實例可區分命名(如 appendonly-6379.aof
)appendfsync AOF 同步策略
-?no
:由操作系統決定何時同步
-?everysecond
:每秒同步一次
-?always
:每次操作都同步everysecond 1. 推薦默認 everysecond
(平衡安全性和性能)
2. 極高安全性需求用always
(性能損耗大)
3. 性能優先且可容忍數據丟失用no
appenddirname AOF 文件存儲子目錄
實際路徑為{dir}/{appenddirname}
無默認值 Redis 7 + 新增參數,建議設置單獨子目錄(如 aof
)便于管理auto-aof-rewrite-percentage AOF 重寫觸發的增長率閾值 100(%) 與 auto-aof-rewrite-min-size
配合使用,默認值可滿足多數場景auto-aof-rewrite-min-size AOF 重寫的最小文件大小閾值 64mb 避免小文件頻繁重寫,可根據業務量調整(如 128mb) no-appendfsync-on-rewrite AOF 重寫期間是否暫停 appendfsync
操作no 1. 設為 yes
可提高重寫速度,但可能增加數據丟失風險
2. 追求安全性保持默認no
(重寫期間仍按策略同步)補充說明
- AOF 重寫可通過
BGREWRITEAOF
命令手動觸發,用于緊急優化 AOF 文件。 - Redis 7 + 的 AOF 重寫會生成
base.rdb
(基礎快照)和incr.aof
(增量操作),結合了 RDB 和 AOF 的優勢。 - 同步策略和重寫參數需根據業務對 "數據安全性" 和 "性能" 的要求綜合調整。
- AOF 重寫可通過
混合持久化策略
- 定義:RDB和AOF兩種持久化策略各有優劣,所以在使用Redis時,是支持同時開啟兩種持久化策略的。
- 開啟方式:在redis.conf配置文件中,有一個aof-use-rdb-preamble參數可以同時打開RDB和AOF兩種持久化策略。但此策略,必須先開啟aof。
- 寫入過程:如果開啟了混合持久化,AOF在重寫時,不再是單純將內存數據轉換為RESP命令寫入AOF文件,而是將重寫這一刻之前的內存做RDB快照處理,并且將RDB快照內容和增量的AOF修改內存數據的命令存在一起,都寫入新的AOF文件,新的文件一開始不叫appendonly.aof,等到重寫完新的AOF文件才會進行改名,覆蓋原有的AOF文件,完成新舊兩個AOF文件的替換。
于是在 Redis 重啟的時候,可以先加載 RDB 的內容,然后再重放增量 AOF 日志就可以完代替替代之前的AOF 全量文件重放,因此重啟效率大幅得到提升。混合持久化AOF文件結構如下:
RDB與AOF對比
對比維度 | RDB(Redis DataBase) | AOF(Append Only File) |
---|---|---|
核心優點 | 1. 文件緊湊,占用存儲空間小,適合定期備份 2. 災難恢復場景中,全量數據恢復效率高 3. 備份時僅 fork 子線程處理,對主線程 IO 性能幾乎無影響 4. 大數據量重啟時,加載速度遠快于 AOF | 1. 安全性更高,默認每秒同步(最多丟失 1 秒數據),支持實時同步(always )2. 采用 “追加寫入” 模式,無記錄不完整問題,可通過 redis-check-aof 工具修復3. 自動觸發日志重寫,避免單個文件過大 4. 日志為可讀的操作指令,可手動編輯(如刪除誤操作 FLUSHALL )實現數據恢復 |
核心缺點 | 1. 僅定期快照,無法實時備份,宕機時可能丟失快照間隔內的所有數據 2. fork 子線程時需克隆內存數據,數據量大 / CPU 性能差時,會導致 Redis 短暫服務停頓 | 1. 相同數據集下,AOF 文件體積通常遠大于 RDB 文件 2. 寫操作頻繁時,IO 開銷更高,備份性能弱于 RDB |
適用場景 | 1. Redis 作為緩存使用,對數據丟失容忍度較高 2. 需定期全量備份、快速恢復的場景 3. 非核心業務數據,優先保障 Redis 運行性能 | 1. 對數據安全性要求高,僅能容忍秒級數據丟失的場景 2. 需避免誤操作導致數據丟失,需手動修復日志的場景 |
持久化策略使用建議
- 如果您只是把Redis當做一個緩存來用,可以直接關閉持久化。
- 如果您更關注數據安全性,并且可以接受服務異常宕機時的小部分數據損失,那么可以簡單的使用RDB策略。這樣性能是比較高的。
- 不建議單獨使用AOF。RDB配合AOF,可以讓數據恢復的過程更快。
Redis數據備份策略建議
-
寫crontab定時調度腳本,每小時都copy一份rdb或aof的備份到一個目錄中去,僅僅保留最近48小時的備份。
-
每天都保留一份當日的數據備份到一個目錄中去,可以保留最近1個月的備份。
-
每次copy備份的時候,都把太舊的備份給刪了。
-
每天晚上將當前機器上的備份復制一份到其他機器上,以防機器損壞。
補充知識
save與bgsave對比
save和bgsave都能生成RDB快照,那么他么有什么區別呢?
他們最大的區別就是save?法會在備份期間阻塞主線程。bgsve則不會阻塞主線程。但是它會fork?個?線程進?持久化,這個過程中會要將數據復制?份,因此會占?更多內存和CPU。具體對比如下:
配置自動生成rdb文件后臺使用的是bgsave方式。
bgsave的寫時復制(COW)機制
Redis 借助操作系統提供的寫時復制技術(Copy-On-Write, COW),在生成快照的同時,依然可以正常處理寫命令。
簡單來說,bgsave 子進程是由主線程 fork 生成的,可以共享主線程的所有內存數據。
bgsave 子進程運行后,開始讀取主線程的內存數據,并把它們寫入 RDB 文件。此時,如果主線程對這些數據也都是讀操作,那么,主線程和 bgsave 子進程相互不影響。但是,如果主線程要修改一塊數據,那么,這塊數據就會被復制一份,生成該數據的副本。然后,bgsave 子進程會把這個副本數據寫入 RDB 文件,而在這個過程中,主線程仍然可以直接修改原來的數據。