阿里面試:Redis掛了怎么辦?集群主節點掛了怎么 恢復數據?可能有多長時間 數據丟失?【轉自】
尼恩說在前面
在45歲老架構師 尼恩的讀者交流群(50+)中,最近有小伙伴拿到了一線互聯網企業如得物、阿里、滴滴、極兔、有贊、希音、百度、網易、美團的面試資格,遇到很多很重要的面試題:
- Redis掛了怎么辦?
- 追問: Redis Cluster 掛一個主節點,是怎么 恢復數據?
- 追問:redis Cluster 主從切換, 可能出現多長時間的數據丟失?
- 追問:Redis cluster 集群里邊的 節點,怎么配置持久化?
最近有小伙伴在面試京東、 阿里、希音等大廠,又遇到了相關的面試題。 小伙伴 沒系統梳理, 支支吾吾的說了幾句, 面試官不滿意,卒。尼恩提示:redis 是多么核心的組件,是多么重要的組件。連 Redis掛了, 竟然不知道怎么處理,怎么可能是技術高手呢?怎么可能 通過面試呢?接下來 45歲老架構師 尼恩給 大家做一下系統化、體系化的梳理。 使得大家內力猛增。幫助大家 充分展示一下 雄厚的 “技術肌肉”,讓面試官愛到 “不能自已、口水直流”,然后實現”offer直提”+”offer自由”。這道 題 以及參考答案, 會收入咱們的 《尼恩Java面試寶典PDF》V175版本,供后面的小伙伴參考 ,幫助大家進大廠/做架構。
最新《尼恩 架構筆記》《尼恩高并發三部曲》《尼恩Java面試寶典》的PDF,請關注本公眾號【技術自由圈】獲取,回復:領電子書
一、面試暴擊:Redis掛了怎么辦?
Redis作為高性能的內存數據庫,在企業應用中扮演著至關重要的角色。然而,由于其數據主要存儲在內存中,一旦服務器發生故障或重啟,所有數據將面臨丟失風險。下面來深入探討Redis持久化機制,幫助您了解如何在Redis服務中斷時最大限度地保障數據安全,并實現快速恢復。Redis 雖然提供了極高的讀寫性能,但宕機也帶來了 性能的嚴重挑戰。當服務器意外宕機或重啟時,內存中的數據將全部丟失,這對于業務系統來說可能是災難性的。
快速止血 流程
Redis 節點掛,會讓人 極度 緊張,需要 一套清晰的應急流程, 幫助應急處理,快速恢復。其處理核心遵循一個清晰的 快速止血 流程: 快速診斷 → 緊急恢復服務 → 數據恢復與根因修復 → 長期優化預防。
第一步:快速診斷與應急恢復
當收到報警或發現應用報錯(如 Connection refused)時,首要目標是確認狀態并盡快恢復基本服務。1、檢查Redis服務狀態:登錄服務器,查看Redis進程是否在運行。執行 ps aux | grep redis命令或 執行 systemctl status redis命令2、查看日志定位原因:如果服務異常,立即查看Redis日志.Redis日志 通常位于 /var/log/redis/redis-server.log 。重點關注:
- 內存不足(Out of memory)
- 持久化失敗(Background save failed)
- 慢查詢(Timeout)
等錯誤信息,這能直接指引排查方向。3、嘗試重啟服務:如果是簡單的進程卡死或配置更新,重啟往往是最快的方法。使用命令
systemctl restart redis- 或
redis-server /path/to/redis.conf命令。
4、啟用應用層降級方案:如果Redis無法立即重啟恢復,為了不影響核心業務,應立即啟動降級策略。包括 讀請求降級、或者寫請求降級:
- 讀請求:直接訪問后端數據庫(如MySQL)。
- 寫請求:先寫入數據庫,并記錄日志或發送消息到消息隊列,待Redis恢復后異步同步數據。
在Java應用中,降級方案 通常通過配置中心動態開關緩存功能,或使用Hystrix、Sentinel等組件實現自動熔斷和降級
第二步:數據恢復
服務進程恢復后,下一步是確保數據完整性。 具體方法取決于您配置的持久化方式。
| 持久化方式 | 恢復原理 | 操作要點 |
| AOF(追加日志) | Redis重啟后重新執行AOF文件中的所有寫命令來重建數據狀態,數據完整性高。 | 確保 appendonly yes配置已開啟,AOF文件路徑正確。 |
| RDB(快照) | Redis啟動時自動加載指定的RDB快照文件(如 dump.rdb)到內存中。 |
將最新的RDB文件放在配置的 dir目錄下。恢復速度快,但可能丟失最后一次快照后的數據。 |
| 從備份恢復 | 如果持久化文件損壞或丟失,需從備份恢復。 | 停止Redis服務 → 用最近的備份文件替換當前數據目錄下的文件 → 重啟Redis。定期備份至關重要。 |
第三步:根因分析與長期優化(事后復盤)
故障解決后,最重要的工作是復盤,防止同類問題再次發生。根因一:集群化部署架構,搭建高可用集群絕對不要在生產環境使用單機Redis。這是最核心的教訓。請根據業務場景選擇:
- Redis Sentinel(哨兵):提供自動故障轉移,適合需要高可用但數據量不大的場景。
- Redis Cluster(集群):提供數據分片(Sharding)和高可用,適合大數據量和超高并發場景。
根因二:配置與監控層面
- 資源限制:在
redis.conf中設置maxmemory并配置合理的maxmemory-policy(內存淘汰策略),防止內存耗盡。 - 全面監控:使用 Prometheus + Grafana 等工具監控內存使用率、連接數、延遲等關鍵指標,并設置告警。
- 處理大Key/熱Key:定期使用
redis-cli --bigkeys分析,并拆分大Key,避免單點瓶頸。
總結:故障處理核心原則
面對Redis故障,請牢記三個關鍵原則:1、快速止血:先通過重啟或降級保障服務可用性,再徹底解決問題 。2、數據為王:依據持久化配置恢復數據,并始終保有可靠的備份 。3、防患未然:通過高可用架構、合理配置和嚴密監控,從根本上提升系統韌性 。
接下來,對面試官來一次 高維暴擊:
到了這里,面試官開始 滿意了。不過, 尼恩提示, 這個時候,可以進一步告訴面試官,咱們線上早期使用單體redis,后面 升級到 集群redis 啦。集群redis 是自動恢復的。單個節點掛了,不用那么手忙腳亂的了。
面試官追問:Redis Cluster 掛一個主節點,是怎么 恢復數據?
還有: 主節點變成從節點后,是從 日志文件恢復數據,還是從 新的主節點恢復數據?
總體的思路是:在 Redis Cluster 中,當主節點故障, 從節點會自動 投票 晉升, 成為 new master 。如果原主節點重啟,首先會從日志文件恢復數據。原主節點 重啟 后,原主節點 降級為 從節點 new slave。接下來, new slave 從 new master 的復制同步 最新增量數據 。
1、故障切換時的數據一致性基礎
故障前, 所有slave 會通過主從復制, 實時同步old master 主節點的數據(通過replicaof機制)。當 old master 主節點宕機時,slave 們 已保存了主節點故障前的大部分數據 。故障轉移后,通過投票,一個slave 從節點 變成 new master 新主節點, 本身就持有接近完整的數據(這里是接近),切換過程中可能出現數據丟失, 這個丟失的時間很短,幾百毫秒~幾秒。
2、原主節點恢復后的角色與數據同步流程
原主節點修復重啟后,會經歷以下過程:1、自身初始化:加載持久化文件(日志的作用)原主節點重啟時,會先加載自身的持久化文件(RDB 或 AOF,取決于配置),恢復到宕機前的狀態。這一步依賴自身的日志文件,但僅能恢復到它宕機時的數據,無法獲取它宕機期間新主節點接收的新數據。2、角色轉換:成為新主節點的從節點重啟后的原主節點會聯系哨兵集群,哨兵會檢測到它已上線,并自動向它發送replicaof 新主節點IP:端口命令,將其設置為新主節點的從節點。3、數據同步:從新主節點復制增量數據此時,原主節點(已成為從節點)會向新主節點發起復制請求,具體分為兩種情況:
- 若原主節點的復制偏移量(宕機前記錄的同步位置)與新主節點的偏移量差距較小,新主節點會發送增量數據(通過 PSYNC 命令,基于偏移量同步缺失的部分)。
- 若差距過大(如新主節點已清理了部分復制積壓緩沖區),新主節點會觸發全量同步:發送自身的 RDB 文件給新從節點(原主節點),新從節點加載 RDB 后,再同步后續的增量數據。
最終,新從節點(原主節點) 會與新主節點(原從)的數據完全一致,包括它宕機期間新主節點接收的所有數據。
3、 數據恢復的兩個來源
- 來源之一:存量恢復。 原主節點的日志文件(RDB/AOF)
將用于重啟時恢復自身宕機前的數據,無法補充它離線期間集群新增的數據。
- 來源之二:增量同步。從新主節點的復制同步
真正讓它與集群保持一致的是從新主節點的復制同步,這是 Redis Cluster 保證數據一致性的核心機制。這種設計的原因是:原主節點宕機, 新主節點在原主宕機后已承接了寫請求,持有最新的數據,原主作為從節點必須以新主的數據為準,才能避免集群數據沖突。
面試官追問:redis Cluster 主從切換, 可能出現多長時間的數據丟失?
Redis 主從切換過程中,數據丟失的時間窗口, 取決于主從同步延遲和切換觸發方式。核心結論:幾百毫秒 ~ 數秒
1、正常情況(異步復制)
丟失時間:幾百毫秒~幾秒原因:主節點異步同步數據到從節點,切換瞬間, 未同步的數據會丟失。舉例:如果主從延遲為 500ms,那么最多可能丟失最近 500ms 內的寫操作。
2、極端情況(配置不當或延遲大)
丟失時間:數秒~分鐘級原因:
- 從節點存在大延遲(如網絡擁堵、從節點性能差)。
- 主節點突然宕機,未來得及同步任何數據。
- 新主節點配置錯誤(如
maxmemory設置過小),導致切換后大量 key 被驅逐,表現為“數據丟失”。
3 如何估算最大可能丟失時間?
Redis 提供了兩個關鍵配置參數,可限制最大數據丟失時間窗口:
| 配置項 | 含義 | 示例值 |
min-slaves-max-lag |
允許的最大主從同步延遲(秒) | 5 |
min-slaves-to-write |
主節點必須連接的從節點數 | 1 |
當所有從節點的同步延遲都超過 min-slaves-max-lag 秒時,主節點會拒絕寫請求,從而將數據丟失時間控制在設定范圍內。
- 設置
min-slaves-max-lag和min-slaves-to-write,強制控制數據丟失時間窗口。 - 監控主從延遲(如
info replication中的lag字段)。
面試官追問:Redis cluster 集群里邊的 節點,怎么配置持久化?
在 Redis Cluster 集群中,每個節點 是獨立的 Redis 實例,持久化配置 每個節點 在 配置文件(redis.conf)中單獨設置。Redis 提供兩種持久化方式:RDB(快照)和 AOF(Append-Only File),可單獨啟用或同時啟用。
(一)、核心持久化配置(適用于集群中所有節點)
以下配置需在每個節點的redis.conf中設置(每個節點的配置文件獨立,需分別修改)。
1. RDB 持久化配置(推薦基礎配置)
RDB 通過定時生成內存快照(二進制文件)實現持久化,適合備份和災難恢復。
# 1. 觸發快照的條件(可配置多個,滿足任一即觸發)
# 格式:save <秒數> <修改次數>
save 60 1000 # 示例:60秒內有1000次修改則生成快照
save 300 10 # 300秒內有10次修改(配置多個,滿足任一即觸發)
save 900 1 # 900秒內有1次修改(配置多個,滿足任一即觸發)
# 2. 禁用RDB(如需完全禁用,注釋所有save指令并添加)
# save ""
# 3. RDB文件名稱(默認dump.rdb)
dbfilename dump-${port}.rdb # 建議添加端口號,避免同一服務器多節點文件沖突
# 4. RDB文件存儲路徑(需確保目錄存在且Redis有寫入權限)
dir /var/lib/redis-cluster/${port}/ # 每個節點建議使用獨立目錄(如按端口區分)
# 5. 快照生成失敗時,是否停止接受寫操作(推薦yes,防止數據丟失)
stop-writes-on-bgsave-error yes
# 6. 是否對RDB文件壓縮(yes節省空間,no節省CPU,推薦yes)
rdbcompression yes
# 7. 是否對RDB文件進行校驗(yes增加安全性,略耗CPU,推薦yes)
rdbchecksum yes
2. AOF 持久化配置(推薦與 RDB 結合使用)
AOF 通過記錄所有寫操作日志(文本指令)實現持久化,數據完整性更高(接近實時)。
# 1. 啟用AOF(默認no,需手動開啟)
appendonly yes
# 2. AOF文件名稱(默認appendonly.aof)
appendfilename "appendonly-${port}.aof" # 建議添加端口號區分
# 3. AOF文件存儲路徑(與RDB相同,共享dir配置)
# dir /var/lib/redis-cluster/${port}/ # 已在RDB中配置,無需重復
# 4. AOF刷盤策略(核心參數,平衡性能與安全性)
# - always:每次寫操作都刷盤(最安全,性能損耗大)
# - everysec:每秒刷盤一次(推薦生產環境,折中方案)
# - no:由操作系統決定刷盤時機(性能好,數據丟失風險高)
appendfsync everysec
# 5. AOF重寫時是否暫停刷盤(推薦yes,避免重寫與刷盤沖突影響性能)
no-appendfsync-on-rewrite yes
# 6. AOF自動重寫觸發條件(避免文件過大)
# 當AOF文件大小比上次重寫后增長100%(即翻倍),且當前大小≥64MB時觸發
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 7. AOF文件損壞時的處理(推薦yes,忽略錯誤部分繼續加載)
aof-load-truncated yes
# 8. 啟用RDB-AOF混合持久化(Redis 4.0+,推薦開啟)
# 重寫AOF時,文件開頭為RDB快照,后續為增量AOF指令,兼顧RDB和AOF優點
aof-use-rdb-preamble yes
(二)、集群環境下的配置注意事項
1、每個節點獨立配置:集群中每個節點(主 / 從)的redis.conf是獨立的,需分別設置持久化參數(尤其是dbfilename和dir,避免同一服務器上的節點文件沖突)。2、主從節點建議均開啟持久化:
- 主節點開啟:確保自身數據可持久化,防止主節點宕機后數據丟失。
- 從節點開啟:防止從節點被選舉為新主節點后,因自身無持久化導致重啟后數據丟失。
3、避免持久化對集群性能的影響:
- RDB 的
bgsave和 AOF 的bgrewriteaof會 fork 子進程,可能短暫阻塞主進程(尤其內存大的節點)。建議在業務低峰期手動觸發(如BGSAVE、BGREWRITEAOF命令),或調整自動觸發條件。 - 若使用 AOF,
appendfsync everysec是性價比最高的選擇(每秒丟失最多 1 秒數據)。
4、定期備份持久化文件:無論 RDB 還是 AOF,都需定期將dir目錄下的持久化文件備份到獨立存儲(如異地備份),防止節點所在服務器故障導致文件丟失。
(三)、配置生效與驗證
1、修改配置后生效:
- 重啟節點:
redis-cli -h 節點IP -p 節點端口 shutdown,再用redis-server /path/to/redis.conf啟動。 - 在線生效(部分參數):通過config set 命令臨時修改(重啟后失效,需同步到redis.conf),例如:
redis-cli -h 127.0.0.1 -p 6379 config set appendonly yes redis-cli -h 127.0.0.1 -p 6379 config rewrite # 將臨時配置寫入redis.conf```bash```
2、驗證配置:使用config get命令查看當前配置,例如:
```bash
# 查看AOF是否啟用
redis-cli -h 127.0.0.1 -p 6379 config get appendonly
# 查看RDB觸發條件
redis-cli -h 127.0.0.1 -p 6379 config get save
3、檢查持久化文件:查看dir目錄下是否生成dump-${port}.rdb或appendonly-${port}.aof文件,例如:
```bash
ls /var/lib/redis-cluster/6379/
(四)、尼恩來一個redis 推薦配置文件
生產環境中,Redis Cluster 建議同時啟用 RDB 和 AOF,結合兩者優勢:
- RDB 適合定時備份和快速恢復(文件小,加載快)。
- AOF 適合保證數據完整性(丟失數據少)。
- 開啟混合持久化(
aof-use-rdb-preamble yes),讓 AOF 文件同時包含 RDB 快照和增量指令,兼顧性能和安全性。
通過以上配置,可確保 Redis Cluster 在節點故障、重啟時最大限度減少數據丟失,同時保證集群的穩定性。尼恩來一個redis 推薦配置文件,如下:
# ==========================================
# Redis 7.x Cluster 生產環境推薦配置模板
# 說明:每個集群節點需單獨配置(端口/路徑需對應修改)
# ==========================================
# ---------------------------
# 基礎身份與路徑配置
# ---------------------------
port 6379 # 節點端口(集群內節點端口需唯一)
daemonize no # 建議設為no,由systemd管理進程(更可靠)
pidfile /var/run/redis_6379.pid # PID文件路徑
dir /data/redis/6379 # 數據文件(RDB/AOF)存儲目錄(需提前創建并授權)
logfile /data/redis/6379/redis.log # 日志文件路徑(目錄需與dir一致)
loglevel notice # 日志級別(notice:生產環境推薦,平衡詳細度與性能)
# ---------------------------
# 集群核心配置
# ---------------------------
cluster-enabled yes # 啟用集群模式
cluster-config-file nodes-6379.conf # 集群元數據文件(自動生成,無需手動修改)
cluster-node-timeout 5000 # 節點心跳超時時間(5秒,超時觸發故障檢測)
cluster-require-full-coverage no # 允許部分槽位不可用時仍提供服務(避免單點故障導致整體不可用)
cluster-migration-barrier 1 # 主節點至少保留1個從節點才允許其他從節點遷移(防止主節點無從可用)
cluster-replica-no-failover no # 允許從節點參與故障轉移(默認no,保持啟用)
# ---------------------------
# 安全配置
# ---------------------------
requirepass YourStrongPassword123! # 訪問密碼(建議包含大小寫+數字+特殊字符,長度≥12位)
masterauth YourStrongPassword123! # 主從同步密碼(必須與requirepass一致)
rename-command FLUSHALL "" # 禁用危險命令(根據業務需求調整,如FLUSHDB、KEYS等)
rename-command FLUSHDB ""
# ---------------------------
# 持久化配置(混合策略)
# ---------------------------
# AOF為主(高數據安全性)
appendonly yes
appendfilename "appendonly-6379.aof"
appendfsync everysec # 每秒刷盤(平衡性能與安全性,最多丟失1秒數據)
no-appendfsync-on-rewrite yes # AOF重寫時暫停刷盤(減少IO沖突,重寫期間仍可能丟失1秒數據)
auto-aof-rewrite-percentage 100 # AOF文件比上次重寫后增長100%時觸發重寫
auto-aof-rewrite-min-size 64mb # AOF文件最小64MB才觸發重寫
aof-use-rdb-preamble yes # 啟用RDB-AOF混合持久化(文件頭部為RDB,尾部為增量指令)
aof-load-truncated yes # 加載AOF時忽略尾部錯誤(避免文件損壞導致啟動失敗)
# RDB為輔助(冷備份+快速恢復)
save 3600 1 # 1小時內有1次修改則生成快照(適合冷備份)
save1800 10 # 30分鐘內10次修改
dbfilename dump-6379.rdb # RDB文件名(含端口區分)
rdbcompression yes # 啟用RDB壓縮(節省磁盤空間)
rdbchecksum yes # 啟用RDB校驗(防止文件損壞)
# ---------------------------
# 主從同步與數據安全
# ---------------------------
# 注意:Redis 5.0+已將slave參數統一改為replica,舊參數已廢棄
min-replicas-to-write 1 # 主節點至少有1個從節點同步正常才接受寫請求
min-replicas-max-lag 5 # 從節點同步延遲≤5秒視為“正常”
replica-serve-stale-data no # 從節點同步中斷時拒絕讀請求(避免返回過期數據)
repl-disable-tcp-nodelay yes # 禁用TCP延遲算法(減少主從同步延遲,輕微增加帶寬)
repl-backlog-size 64mb # 主從斷開后,主節點保留64MB的寫操作緩沖區(加速重連后同步)
repl-backlog-ttl 3600 # 緩沖區無從節點連接時,保留1小時后釋放
# ---------------------------
# 內存管理與淘汰策略
# ---------------------------
maxmemory 2gb # 節點最大可用內存(根據服務器配置調整,建議留20%余量)
maxmemory-policy noeviction # 內存滿時拒絕寫請求(集群模式禁用淘汰,避免數據不一致)
maxmemory-samples 5 # 淘汰策略采樣數量(平衡精度與性能)
lazyfree-lazy-eviction yes # 異步釋放內存(減少刪除大鍵時的阻塞)
lazyfree-lazy-expire yes # 異步處理過期鍵刪除
# ---------------------------
# 網絡與性能優化
# ---------------------------
tcp-backlog 511 # TCP連接隊列大小(需配合內核net.core.somaxconn)
timeout 0 # 客戶端空閑超時(0表示永不超時)
tcp-keepalive 300 # 5分鐘發送一次TCP保活探測(檢測死連接)
client-output-buffer-limit normal 0 0 0 # 普通客戶端無緩沖區限制(按需調整)
client-output-buffer-limit replica 512mb 128mb 60 # 從節點緩沖區:超過512MB或128MB持續60秒則斷開
io-threads 4 # 啟用4個IO線程(Redis 6.0+,值為CPU核心數的1/2最佳)
io-threads-do-reads yes # IO線程處理讀操作(提升吞吐量)
# ---------------------------
# 慢查詢與監控
# ---------------------------
slowlog-log-slower-than 10000 # 記錄執行時間>10ms的命令(微秒)
slowlog-max-len 2048 # 慢查詢日志最多保留2048條
latency-monitor-threshold 100 # 記錄延遲>100ms的操作(便于排查性能問題)
# ---------------------------
# 系統級優化建議(需配合操作)
# ---------------------------
# 1. 內核參數(/etc/sysctl.conf):
# net.core.somaxconn = 1024
# vm.overcommit_memory = 1
# net.ipv4.tcp_max_tw_buckets = 65536
# 2. 禁用透明大頁:
# echo never > /sys/kernel/mm/transparent_hugepage/enabled
# 3. 資源限制(/etc/systemd/system/redis.service):
# LimitNOFILE=1000000
# LimitNPROC=1000000
# 4. 監控重點:
# - cluster_info 集群狀態
# - info replication 主從同步狀態(lag值)
# - info memory 內存使用率
# - info persistence AOF/RDB持久化狀態
二、擴展學習:AOF持久化原理
Redis提供了三種持久化方案
作為基礎知識,需要 深入介紹一下 Redis提供了三種持久化方案:
- AOF(Append Only File):實時記錄每一條寫命令,恢復時“重播”命令就能還原數據。
- RDB(Redis DataBase):在指定時間點拍個“快照”,把當時的全量數據存到磁盤,恢復時直接加載快照。
- 混合持久化:結合AOF和RDB的優點,用RDB存全量數據,用AOF存增量命令,兼顧安全和性能。
先從AOP講起
1、AOF工作原理
AOF(Append Only File)持久化通過實時記錄每一條寫命令到日志文件中,在服務重啟時重新執行這些命令來恢復數據。與MySQL等數據庫采用的寫前日志(Write Ahead Log,WAL)不同,Redis AOF采用寫后日志機制。寫后日志的優勢:
- 先執行命令再進行日志記錄,避免了記錄錯誤命令的可能性
- 不會阻塞當前的寫操作執行
- 簡化了日志記錄的邏輯處理
寫后日志的缺點:
- 如果執行完一個命令還沒來得及寫日志就宕機了會造成響應數據丟失。
- AOF 的寫入由主線程處理,如果寫入時出現較長耗時,那就會影響主線程處理后續的請求。
AOF通過記錄每個寫操作命令來持久化數據。當Redis重啟時,會重新執行AOF文件中的所有命令,從而恢復數據狀態。
2、AOF配置與開啟方式
AOF功能默認關閉,需要通過以下方式開啟:
# 配置文件方式(redis.conf)
appendonly yes
# 命令行動態配置
redis-cli config set appendonly yes
3、AOF寫回策略
Redis提供了三種AOF寫回策略,滿足不同場景下的數據安全與性能需求:
| 策略 | 機制 | 優點 | 缺點 | 適用場景 |
| Always | 同步寫回,每條命令執行后立即刷盤 | 數據可靠性最高,幾乎不丟失 | 性能影響大,每次寫操作都需磁盤IO | 對數據安全要求極高的場景 |
| Everysec | 每秒寫回,異步刷盤 | 性能與可靠性平衡 | 可能丟失1秒內的數據 | 大多數業務場景的默認選擇 |
| No | 由操作系統控制寫回時機 | 寫入性能最佳 | 可靠性差,可能丟失大量數據 | 可容忍數據丟失的非關鍵業務 |
配置方式:
# 修改redis.conf配置文件
appendfsync everysec
# 或通過命令行設置
redis-cli config set appendfsync everysec
4、AOF 配置項
在 Redis 配置文件 redis.conf中,AOF 持久化提供了多個可配置參數,用于精細控制 AOF 的行為和特性。下表對這些配置項進行了系統梳理和說明:
| 配置項 | 默認值 | 可選值 | 說明 |
| appendonly | no | yes/no | 是否開啟 AOF 持久化功能。 ? no: 關閉 ? yes: 開啟 |
| appendfilename | "appendonly.aof" | 自定義文件名 | 指定 AOF 文件的名稱。 |
| dir | ./ | 自定義目錄路徑 | 指定 AOF 文件(及 RDB 文件)的存儲目錄。 |
| appendfsync | everysec | always/everysec/no | AOF 日志寫回磁盤的策略: ? always: 同步寫回,每個寫命令執行完立即刷盤,可靠性最高但性能影響大 ? everysec: 每秒寫回,在可靠性和性能之間取得平衡 ? no: 由操作系統控制寫回時機,性能最好但可靠性最差 |
| no-appendfsync-on-rewrite | no | yes/no | 是否在 AOF 重寫或 RDB 持久化期間,禁止主進程進行 AOF 刷盤: ? no: 允許刷盤,可能因磁盤 IO 壓力阻塞主線程 ? yes: 禁止刷盤,避免阻塞但可能丟失更多數據 生產環境建議: 寫操作多時設為 yes,讀操作多時設為 no |
| auto-aof-rewrite-percentage | 100 | 正整數 | AOF 文件大小比上次重寫后大小增長的百分比閾值,達到此閾值則觸發重寫。 例如設置為 100,表示當前 AOF 文件大小是上次重寫后大小的 2 倍(即增長 100%)時觸發。 |
| auto-aof-rewrite-min-size | 64mb | 單位:kb, mb, gb | 觸發 AOF 重寫的最小文件大小。即使增長百分比達到要求,但文件大小未達到此值也不會觸發重寫。 |
| aof-load-truncated | yes | yes/no | 當 Redis 啟動時發現 AOF 文件被截斷(可能因宕機導致最后一條命令不完整)是否繼續加載: ? yes: 截斷不完整命令,正常啟動 ? no: 拒絕啟動,需手動修復 AOF 文件 |
| aof-use-rdb-preamble | yes | yes/no | 是否開啟混合持久化模式(Redis 4.0+): ? yes: AOF 重寫時先以 RDB 格式寫入全量數據,再追加增量 AOF 日志 ? no: 僅使用純 AOF 格式 |
提示:修改配置可通過直接編輯redis.conf文件,或使用CONFIG SET parameter value命令在線動態調整(重啟后失效,需手動修改配置文件以持久化變更)。
5、AOF文件格式與內容
AOF文件以Redis協議格式記錄命令,例如執行set testkey testvalue后,AOF文件中會記錄:
*3
$3
set
$7
testkey
$9
testvalue
*3表示命令有3個部分$3表示接下來的部分有3個字節("set")- 后續類似格式分別表示鍵和值
6、AOF 重寫:解決日志膨脹的智能機制
6.1 為什么需要 AOF 重寫?
讓我們從一個實際場景入手:假設我們對同一個鍵 testkey先后執行了多次寫操作:
set testkey testvalue
set testkey value
在傳統的 AOF 記錄方式下,所有這些操作都會被完整記錄在 AOF 文件中。但當我們進行數據恢復時,實際上只需要最后一條命令 set testkey value就能恢復到最終狀態,第一條命令成了"冗余數據"。這就是 AOF 重寫要解決的核心問題:消除歷史冗余命令,壓縮文件體積。隨著系統運行時間增長,AOF 文件中會積累大量這樣的冗余記錄,導致文件不斷膨脹,不僅占用大量磁盤空間,還會影響數據恢復速度。
6.2 AOF 重寫的工作原理
AOF 重寫的核心思想很巧妙:不再分析舊的 AOF 文件,而是直接讀取當前數據庫狀態,然后生成一條條能夠重現當前數據狀態的命令。舉個例子,如果一個列表鍵經歷了以下操作:最終列表狀態為
["D", "E","F"]。重寫后,AOF 文件只需要記錄:
LPUSH mylist “D”, “E”, "F"
這一條命令就能重現最終狀態,相比原來的 6 條命令,壓縮效果明顯。
6.3 AOF 重寫的執行流程
為了避免重寫過程阻塞主線程,Redis 使用 fork 創建子進程來完成重寫任務。下面是詳細的執行流程:
- Redis 在接收到一條客戶端發送過來的寫命令后,會先執行該寫命令,待命令執行成功后將該命令按照 Redis 通信協議格式寫入 AOF 緩沖區。
- 根據設置的 AOF 寫回策略,當滿足寫回條件時,將 AOF 緩沖區中的數據寫入磁盤 AOF 文件中。
- 當 AOF 文件大小達到重寫條件后,主進程 fork 出 bgrewriteaof 子進程,由子進程將內存中的數據重寫為寫命令寫入臨時文件。
- 若重寫期間,主線程執行了新的寫操作,主線程在將該寫操作記錄到 AOF 緩沖區的同時會將該寫操作寫入重寫緩存區。
- 待子進程完成內存中數據的記錄后,會將重寫緩存區記錄的數據一并寫入臨時文件。
- 最后利用臨時文件替換原來的 AOF 文件。
重寫期間的新寫操作會同時寫入兩個緩沖區:
- AOF緩沖區:按正常流程同步到現有AOF文件
- 重寫緩沖區:專門用于保存重寫期間的新操作
當子進程完成重寫后,主進程會將重寫緩沖區的內容追加到新的AOF文件,確保數據完整性。這個流程的關鍵點在于:1、非阻塞設計:重寫工作由子進程完成,主進程繼續正常服務2、數據一致性保障:通過重寫緩沖區確保重寫期間的新寫操作不丟失3、原子性替換:使用臨時文件+重命名機制確保替換操作的原子性
6.4 重寫觸發條件與配置
AOF 重寫支持手動和自動兩種觸發方式:手動觸發:
# 立即啟動AOF重寫
redis-cli BGREWRITEAOF
自動觸發條件(需同時滿足):(1) 當前沒有 RDB 持久化或 AOF 重寫正在進行(2) AOF 文件大小 ≥ auto-aof-rewrite-min-size(默認 64MB)(3) AOF 文件大小比上次重寫后大小增長 ≥ auto-aof-rewrite-percentage(默認 100%)配置示例:
# 最小重寫大小閾值
auto-aof-rewrite-min-size 64mb
# 增長百分比閾值
auto-aof-rewrite-percentage 100
7、AOF優缺點分析
優點:(1)AOF 可以更好的保護數據不丟失,一般 AOF 會每隔1秒,通過一個后臺線程執行 fsync 操作,最多丟失 1 秒鐘的數據。(2)Redis 提供了 AOF 文件的重寫機制,因此 AOF 日志文件不會膨脹的很大,并且在重寫期間也不會影響客戶端的讀寫。(3)AOF 文件中保存的是執行的指令,所以這個特性非常適合做災難性的誤操作緊急恢復。缺點:(1)由于 AOF 文件中記錄的是寫操作的命令,因此對于同一份數據來說,AOF 的日志文件通常要比 RDB 的數據快照文件要大。(2)AOF 開啟之后,Redis 服務支持的寫 QPS 會比 RDB 支持的寫 QPS 低。
三、擴展學習:RDB持久化 原理
1、RDB核心概念
RDB(Redis DataBase)通過創建內存數據的時間點快照實現持久化。它將某一時刻的所有數據以二進制格式保存到磁盤文件中。
2、RDB觸發方式
1. save命令(同步方式,不推薦生產使用)save命令是主線程自己執行RDB,期間會完全阻塞Redis,不能處理任何客戶端請求。如果數據量大,可能阻塞幾秒甚至幾分鐘,生產環境絕對不能用。
redis-cli save
# 執行期間阻塞所有客戶端請求
2. bgsave命令(異步方式,推薦使用)bgsave是“background save”的縮寫,主線程會fork一個子進程,由子進程執行RDB,主線程繼續處理請求。只有fork子進程的瞬間會短暫阻塞(毫秒級),幾乎不影響業務。
redis-cli bgsave
# 后臺異步執行,僅fork階段短暫阻塞
3. 自動觸發在redis.conf里配置save m n,表示“m秒內有n次寫操作”,就自動觸發bgsave。
# 3個條件,滿足任意一個就觸發bgsave
save 900 1 # 900秒(15分鐘)內有1次寫操作
save 300 10 # 300秒(5分鐘)內有10次寫操作
save 60 10000 # 60秒內有10000次寫操作
比如QPS=1000的場景,60秒內會有60000次寫操作,會觸發bgsave;如果QPS低,15分鐘內有1次寫操作也會觸發,保證數據不會丟太多。4、三種觸發方式的對比:
| 觸發方式 | IO類型 | 是否阻塞主線程 | 優點 | 缺點 |
| save | 同步 | 是(完全阻塞) | 不消耗額外內存(無fork) | 阻塞業務,生產禁用 |
| bgsave | 異步 | 僅fork時阻塞 | 不影響業務 | fork子進程消耗內存(復制頁表) |
| 自動觸發 | 異步 | 僅fork時阻塞 | 無需手動操作 | 可能頻繁觸發(需合理配置m和n) |
3、RDB 配置項
在Redis配置文件(redis.conf)中,除了用于開啟RDB功能的save配置項外,還提供了多個用于自定義RDB行為的配置參數。如下:
| 配置項 | 可選值 | 默認值 | 功能說明 | 性能與可靠性影響 |
| stop-writes-on-bgsave-error | yes/no | yes | 當RDB持久化失敗時是否停止接收寫操作 | 設置為yes可避免數據不一致,但會增加服務不可用風險 |
| rdbcompression | yes/no | yes | 是否對RDB文件進行LZF壓縮 | 壓縮減少磁盤空間占用,但增加CPU消耗 |
| rdbchecksum | yes/no | yes | 是否在RDB文件末尾添加CRC64校驗和 | 校驗保證數據完整性,但增加少量CPU開銷 |
| dbfilename | 字符串 | dump.rdb | 指定RDB文件名 | 僅影響文件命名,無性能影響 |
| dir | 路徑 | ./ | 指定RDB文件存儲目錄 | 影響文件存儲位置,建議使用高性能磁盤 |
| rdb-del-sync-files | yes/no | no | 是否在沒有持久化時刪除同步文件 | 主要用于復制環境,對單實例影響較小 |
配置示例:
# Redis配置文件片段示例
stop-writes-on-bgsave-error yes # bgsave失敗時拒絕寫入,確保數據一致性
rdbcompression yes # 啟用LZF壓縮算法,減少磁盤占用
rdbchecksum yes # 啟用CRC64校驗,保證RDB文件完整性
dbfilename dump.rdb # 指定RDB文件名稱
dir /var/lib/redis/ # 設置RDB文件存儲路徑
4、寫時復制技術(Copy-On-Write)
COW詳細內容參考:阿里面試:什么是COW(Copy-on-Write)技術? 探討一下在mvcc、Java中的應用場景、實現原理及優缺點bgsave子進程在寫RDB的時候,主線程還在修改數據,會不會導致RDB文件里的數據混亂?答案是不會,因為Redis用了寫時復制(Copy-On-Write,COW) 技術——這是操作系統提供的內存優化機制,核心邏輯是“讀共享,寫復制”。簡單說:
- fork后,主線程和子進程共享同一塊內存,子進程只讀不寫;
- 主線程要修改數據"C"時,會先復制一份該數據的“副本C`”,在副本上修改;
- 子進程寫RDB用的還是原來的舊數據,保證快照是“fork時刻”的完整數據;
- 只復制“要修改的頁”(內存按頁管理,通常4KB/頁),不是全量復制,內存消耗小。
5、RDB文件結構
RDB文件格式包含五個部分:1、SOF:5字節"REDIS"字符串,標識文件類型2、rdb_version:4字節版本號3、database:包含多個數據庫的數據4、EOF:1字節結束標志5、check_sum:8字節校驗和,用于驗證文件完整性
6、RDB優缺點分析
優勢:
- 數據恢復速度快(直接加載到內存)
- 文件體積小(二進制壓縮格式)
- 最大化Redis性能(最小化持久化對性能的影響)
劣勢:
- 可能丟失最后一次快照后的所有數據
- fork過程可能阻塞主進程(尤其在大數據集時)
- 不支持細粒度恢復(只能恢復到快照時間點)
四、混合持久化:兼顧安全與效率
1、什么是混合持久化
RDB 快照有個問題:兩次快照之間的數據可能丟失,而快照太頻繁又影響性能。所以 Redis 4.0 出了個混合持久化辦法,能通過配置aof-use-rdb-preamble開啟。簡單說就是:用 AOF 日志記錄兩次快照之間的操作,這樣 AOF 文件不會太大,也不用頻繁重寫。比如,T1 到 T2 之間的修改用 AOF 記著,等第二次全量快照做好后,就把 AOF 日志清掉(因為修改已經進快照了),恢復數據時也不用再看日志了。
4.2 配置混合持久化
混合持久化需要配合AOF重寫使用——開啟后,新的AOF文件會變成“RDB+AOF”格式。方式1:修改redis.conf(永久生效)
# 開啟混合持久化(Redis 4.0+支持,Redis 6.0+默認yes)
aof-use-rdb-preamble yes
# 同時確保AOF是開啟的
appendonly yes
方式2:在線開啟(臨時生效)
# 1. 開啟混合持久化
127.0.0.1:6379> config set aof-use-rdb-preamble yes
OK
# 2. 觸發AOF重寫,生成混合格式的AOF文件
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
# 3. 持久化配置(避免重啟失效)
127.0.0.1:6379> config rewrite
OK
混合持久化配置后,AOF文件的結構是這樣的:
- 前半部分:RDB格式的全量數據
- 后半部分:AOF格式的增量寫命令
五、持久化方案選擇與實戰建議
方案對比與選型指南:
| 考量因素 | RDB | AOF | 混合模式 |
| 數據安全 | 可能丟失分鐘級數據 | 最多丟失1秒數據 | 最多丟失1秒數據 |
| 恢復速度 | 快 | 慢 | 中等 |
| 文件大小 | 小 | 大 | 中等 |
| 性能影響 | 低(fork時短暫影響) | 中(依賴寫回策略) | 中 |
| 適用場景 | 可容忍數據丟失 需要快速恢復 備份與災難恢復 | 數據安全性要求高 可承受性能代價 | 生產環境推薦方案 平衡性能與安全 |
通用場景推薦配置:
# 開啟混合持久化
aof-use-rdb-preamble yes
# RDB配置
save 900 1
save 300 10
save 60 10000
# AOF配置
appendonly yes
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
數據敏感型場景:
appendfsync always # 每條命令都刷盤
性能優先場景:
appendfsync no # 由操作系統控制刷盤
轉自
https://mp.weixin.qq.com/s/c1dZBIAImU4QP597aOe_6A

浙公網安備 33010602011771號