Redis 持久化的核心目的是 防止內(nèi)存數(shù)據(jù)丟失—— 將內(nèi)存中的鍵值對以特定格式寫入磁盤,當(dāng) Redis 重啟(如宕機(jī)、重啟服務(wù))時(shí),可從磁盤文件恢復(fù)數(shù)據(jù),平衡 “數(shù)據(jù)安全性” 和 “性能開銷”。Redis 提供兩種核心持久化方案:RDB(Redis DataBase) 和 AOF(Append Only File)
一、RDB 持久化(快照持久化)
1. 核心原理
RDB 是 基于時(shí)間點(diǎn)的快照:在指定時(shí)間間隔內(nèi),若滿足 “修改操作數(shù)閾值”,Redis 會觸發(fā)后臺進(jìn)程(fork 出子進(jìn)程 rdbSave),將當(dāng)前內(nèi)存中的 全量數(shù)據(jù) 以二進(jìn)制格式寫入磁盤文件(默認(rèn) dump.rdb),快照生成期間父進(jìn)程繼續(xù)處理客戶端請求,不阻塞(寫時(shí)復(fù)制 COW 機(jī)制保證數(shù)據(jù)一致性)。
2. 觸發(fā)方式
- 自動觸發(fā):通過配置文件 redis.conf 定義規(guī)則,格式為 save <seconds> <changes>,例如:
save 900 1 # 900秒內(nèi)至少1次修改
save 300 10 # 300秒內(nèi)至少10次修改
save 60 10000 # 60秒內(nèi)至少10000次修改
滿足任一規(guī)則即觸發(fā)快照;若注釋所有 save 項(xiàng),自動觸發(fā)失效。
手動觸發(fā):
save 命令:主進(jìn)程直接執(zhí)行快照,期間阻塞所有客戶端請求(不推薦生產(chǎn)環(huán)境);
bgsave 命令:主進(jìn)程 fork 子進(jìn)程執(zhí)行快照,父進(jìn)程無阻塞(生產(chǎn)常用)。特殊觸發(fā):Redis 關(guān)閉(shutdown 命令)或主從復(fù)制時(shí)(從節(jié)點(diǎn)連接主節(jié)點(diǎn)后,主節(jié)點(diǎn)會觸發(fā) bgsave 生成快照發(fā)送給從節(jié)點(diǎn))。
3. 優(yōu)缺點(diǎn)
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| 二進(jìn)制文件,體積小、加載速度極快(重啟恢復(fù)效率高) | 快照間隔內(nèi)數(shù)據(jù)丟失風(fēng)險(xiǎn)(如 60 秒規(guī)則,宕機(jī)可能丟失最近 60 秒數(shù)據(jù)) |
| 備份 / 遷移方便(直接拷貝 dump.rdb 即可) | fork 子進(jìn)程開銷大(數(shù)據(jù)量越大,fork 耗時(shí)越長,可能短暫阻塞) |
| 恢復(fù)時(shí)直接加載全量數(shù)據(jù),性能優(yōu)于 AOF | 全量快照,頻繁觸發(fā)會占用大量磁盤 I/O 帶寬 |
二、AOF 持久化(日志持久化)
1. 核心原理
AOF 是 基于操作日志的持久化:Redis 每執(zhí)行一條 “寫命令”(如 set、hmset),就會將命令追加到內(nèi)存緩沖區(qū)(aof_buf),再通過配置的 “刷盤策略” 寫入磁盤文件(默認(rèn) appendonly.aof);重啟時(shí),Redis 會重新執(zhí)行 AOF 文件中的所有命令,還原內(nèi)存數(shù)據(jù)。
2. 關(guān)鍵配置
- 開啟 AOF:默認(rèn)關(guān)閉,需在 redis.conf 中設(shè)置 appendonly yes;
- 刷盤策略(決定數(shù)據(jù)安全性和性能的平衡,通過 appendfsync 配置):
appendfsync always # 每執(zhí)行1條寫命令,立即刷盤(最高安全性,性能最差,IO開銷大)
appendfsync everysec # 每秒刷盤1次(默認(rèn),折中方案:最多丟失1秒數(shù)據(jù),性能較優(yōu))
appendfsync no # 由操作系統(tǒng)決定刷盤時(shí)機(jī)(性能最好,數(shù)據(jù)丟失風(fēng)險(xiǎn)最高)
- AOF 重寫:解決 AOF 文件膨脹問題(如多次 set key value 可合并為 1 條):
- 原理:Redis fork 子進(jìn)程,遍歷內(nèi)存數(shù)據(jù)生成 “最終狀態(tài)命令”(如 hmset 替代多次 hset),寫入新 AOF 文件,完成后替換舊文件;
- 觸發(fā)方式:
- 自動觸發(fā):auto-aof-rewrite-min-size 64mb(AOF 文件超 64MB)且 auto-aof-rewrite-percentage 100(文件體積比上次重寫后增長 100%);
- 手動觸發(fā):bgrewriteaof 命令。
3. 優(yōu)缺點(diǎn)
| 優(yōu)點(diǎn) | 缺點(diǎn) |
|---|---|
| 數(shù)據(jù)安全性高(可配置每秒 / 每條刷盤,最多丟失 1 秒數(shù)據(jù)) | AOF 文件體積大(未重寫時(shí)),加載恢復(fù)速度慢于 RDB |
| 日志是文本格式,可手動修復(fù)錯誤命令(如誤刪后編輯 AOF) | 寫命令追加 + 重寫有一定性能開銷(但默認(rèn)刷盤策略影響較?。?/td> |
| 支持 “秒級數(shù)據(jù)恢復(fù)”,適合對數(shù)據(jù)一致性要求高的場景 | 重寫時(shí) fork 子進(jìn)程仍有短暫阻塞風(fēng)險(xiǎn)(同 RDB) |
三、RDB vs AOF 核心對比
| 維度 | RDB | AOF |
|---|---|---|
| 數(shù)據(jù)安全性 | 低(快照間隔內(nèi)丟失) | 高(可配置刷盤策略) |
| 文件體積 | 小(二進(jìn)制全量快照) | 大(文本命令追加) |
| 恢復(fù)速度 | 快(直接加載全量數(shù)據(jù)) | 慢(重新執(zhí)行所有命令) |
| 寫性能 | 好(僅快照時(shí)開銷) | 一般(每秒 / 每條刷盤) |
| 適用場景 | 數(shù)據(jù)備份、主從復(fù)制、允許少量數(shù)據(jù)丟失的場景 | 金融、電商等對數(shù)據(jù)一致性要求高的場景 |
四、實(shí)際應(yīng)用方案(面試高頻)
- 組合使用(推薦生產(chǎn)環(huán)境)
核心思路:用 AOF 保證數(shù)據(jù)安全性(每秒刷盤,最多丟 1 秒數(shù)據(jù)),用 RDB 做全量備份(如每天凌晨觸發(fā) bgsave);
恢復(fù)邏輯:Redis 重啟時(shí),優(yōu)先加載 AOF 文件(數(shù)據(jù)更完整),若 AOF 文件不存在 / 損壞,再加載 RDB 文件;
優(yōu)勢:兼顧 “數(shù)據(jù)安全” 和 “恢復(fù)效率”,同時(shí) RDB 可作為災(zāi)難恢復(fù)的兜底方案(如 AOF 文件損壞時(shí)用 RDB 恢復(fù))。 - 僅用 RDB
適用場景:數(shù)據(jù)可容忍分鐘級丟失(如緩存場景)、追求極致恢復(fù)速度、備份 / 遷移頻繁的場景;
注意:需合理配置 save 規(guī)則(如 save 3600 1,每小時(shí) 1 次修改即快照),避免頻繁 fork 阻塞。 - 僅用 AOF
適用場景:對數(shù)據(jù)一致性要求極高(如不允許丟失任何數(shù)據(jù),配置 appendfsync always);
注意:需監(jiān)控 AOF 文件大小,避免膨脹導(dǎo)致磁盤溢出,定期手動觸發(fā) bgrewriteaof。 - 禁用持久化
適用場景:純緩存場景(數(shù)據(jù)可從后端數(shù)據(jù)庫重建),追求 Redis 極致性能(避免持久化 IO 開銷)。 - AOF 為什么會出現(xiàn)文件損壞?如何修復(fù)?
損壞原因:Redis 宕機(jī)時(shí),AOF 緩沖區(qū)數(shù)據(jù)未刷盤,導(dǎo)致文件末尾命令不完整;
修復(fù)方式:使用 Redis 自帶工具 redis-check-aof --fix appendonly.aof,工具會刪除損壞的命令,保留有效部分,修復(fù)后重啟 Redis 即可加載。 - 持久化對 Redis 性能的影響如何優(yōu)化?
避免高峰時(shí)段觸發(fā) RDB/AOF 重寫(如定時(shí)在凌晨低峰期執(zhí)行 bgsave);
合理配置 fork 時(shí)機(jī):數(shù)據(jù)量不宜過大(如控制在 10GB 內(nèi)),避免 fork 耗時(shí)過長;
調(diào)整刷盤策略:生產(chǎn)環(huán)境優(yōu)先 appendfsync everysec,兼顧性能和安全;
磁盤選型:使用 SSD 降低 IO 延遲,減少持久化對性能的影響。