03.3 - 混合持久化与最佳实践
定位: Redis 4.0 引入的混合持久化——整合 RDB 的快速恢复和 AOF 的低丢失 面试高频度: ⭐⭐⭐⭐ 考查方式: 混合持久化原理、AOF+RDB 的加载顺序、生产配置方案
一、这是什么?为什么需要它?
是什么
混合持久化(Redis 4.0+)在 AOF rewrite 时,先生成一个 RDB 快照作为基线数据,再追加 RDB 快照之后的增量命令。AOF 文件 = RDB 头部 + AOF 增量尾部。
为什么需要混合持久化?
RDB 单独使用的痛点: 电商大促场景:
- 上一轮 RDB 在 12:00 完成
- 12:01-12:15 产生 100 万次写入
- 12:15 宕机
- rdb_last_save_time: 12:00
- 100 万次写入丢失
AOF 单独使用的痛点: 100GB 数据的 Redis 宕机重启:
- 纯 AOF:重放 100 亿条命令
- 恢复需要 1 小时,业务不可用 1 小时!
混合持久化: 既开 RDB 又开 AOF:
- 先用 RDB 做"快速基础恢复"(几分钟)
- 再用 AOF 补"增量数据"(十多秒)
- 恢复时间 = RDB加载时间 + AOF增量时间
- 比纯 AOF 快 10-100 倍
二、原理拆解
2.1 混合持久化的 AOF 文件格式
2.2 加载顺序与流程
AOF 加载的两种子情况:
- 普通 AOF: 从头到尾重放所有命令 O(N)
- 混合 AOF: 先加载 RDB 段(Jemalloc 直接加载),再执行 AOF 段的增量命令
- 加载速度 = RDB 加载时间 + 增量命令执行时间
2.3 生产配置推荐
conf
# ============ 持久化配置推荐 ============
# 1. AOF 开启(推荐)
appendonly yes
appendfsync everysec
# 2. 混合持久化开启(Redis 4.0+)
aof-use-rdb-preamble yes
# 3. AOF 自动 rewrite 策略
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 4. RDB 保留策略(用于灾难恢复)
save 900 1
save 300 10
save 60 10000
# 5. 停止写入策略(磁盘满时保护)
no-appendfsync-on-rewrite yes # rewrite 期间不 fsync,避免磁盘竞争
# 6. 子进程写入策略
rdbcompression yes # RDB 压缩(节省磁盘但多耗 CPU)
rdbchecksum yes # RDB 校验(安全但多耗 5-10% CPU)2.4 不同场景的持久化策略
yaml
场景: "缓存"
- 数据可丢失
- 关闭持久化(最大性能)
- 配置: save ""(关闭 RDB)+ appendonly no
场景: "缓存+持久化"
- 数据不能全丢
- 主库开 AOF everysec + 混合持久化
- 从库开 RDB(用于备份/从节点恢复)
场景: "数据库级使用"
- 数据不能丢
- AOF everysec + always(关键数据)
- 主库 AOF + 从库 RDB 双保险
- 定期 S3 备份 RDB 文件
场景: "大容量 Redis(>32GB)"
- fork 代价大 → 只在从节点做持久化
- 主节点不持久化(关闭 RDB+AOF)
- 从节点持久化 + 定期备份
- 主节点宕机→从节点升级为主三、图解全景
四、实战验证
4.1 查看当前持久化配置
bash
redis-cli
# AOF 状态
127.0.0.1:6379> CONFIG GET appendonly
1) "appendonly"
2) "yes"
# 混合持久化
127.0.0.1:6379> CONFIG GET aof-use-rdb-preamble
1) "aof-use-rdb-preamble"
2) "yes"
# fsync 策略
127.0.0.1:6379> CONFIG GET appendfsync
1) "appendfsync"
2) "everysec"
# RDB 规则
127.0.0.1:6379> CONFIG GET save
1) "save"
2) "3600 1 300 100 60 10000" # 多条规则空格分隔4.2 混合持久化文件分析
bash
# 确认 AOF 文件已开启混合模式
file /var/lib/redis/appendonly.aof
# appendonly.aof: Redis AOF file, RDB preamble (mixed format)
# 查看混合 AOF 文件头部
hexdump -C /var/lib/redis/appendonly.aof | head -5
# 00000000 52 45 44 49 53 30 30 30 39 fa ... (REDIS0009 是 RDB 头)
# 对比两种模式的 AOF 恢复时间
# 测试 10GB Redis 的恢复时间
# 纯 AOF: ~30 分钟
# 混合 AOF: ~3 分钟(RDB 加载 2 分钟 + 增量 1 分钟)4.3 模拟崩溃恢复测试
bash
# 1. 开启混合持久化
redis-cli CONFIG SET appendonly yes
redis-cli CONFIG SET aof-use-rdb-preamble yes
# 2. 写入 10000 个 key
for i in $(seq 1 10000); do
redis-cli SET "key:$i" "value:$i" > /dev/null
done
# 3. 手动触发混合持久化(BGREWRITEAOF)
redis-cli BGREWRITEAOF
sleep 5
# 4. 再写入一些数据(模拟增量)
redis-cli SET "last-key" "should-be-there"
# 5. 模拟崩溃
sudo systemctl stop redis
# 6. 确认 AOF 文件存在
ls -la /var/lib/redis/appendonly.aof
# 7. 启动
sudo systemctl start redis
# 8. 验证数据
redis-cli DBSIZE
# (integer) 10001 ← 所有 key 都恢复了
redis-cli GET "last-key"
# "should-be-there" ← 崩溃前的增量数据也在五、面试视角
| 追问 | 答案要点 |
|---|---|
| 混合持久化的 AOF 文件结构? | RDB 头部(全量快照)+ AOF 尾部(增量命令),BGREWRITEAOF 时生成 |
| 混合持久化的加载流程? | Redis 启动 → 加载 AOF 文件 → 发现 RDB 头 → 先加载 RDB 段 → 再执行 AOF 增量命令 |
| 为什么混合持久化恢复快? | RDB 段是二进制内存快照(Jemalloc 直接加载),只需回放少量 AOF 增量命令 |
| 生产推荐的持久化方案? | 主节点 AOF everysec + 混合模式;从节点开 RDB;或主节点不持久化,从节点持久化 |
| 大内存实例的持久化策略? | 主节点关闭持久化(避免 fork 阻塞),从节点开启 AOF+RDB;主从切换时从提升为主 |
| 混合持久化的缺点? | AOF 文件比纯 RDB 大,比纯 AOF 小(折中);rewrite 时仍需要 fork |
| 如果 AOF 和 RDB 同时开,Redis 用哪个恢复? | 优先用 AOF(数据最完整);AOF 不存在则用 RDB |
📚 相关链接
- **RDB 快照** — 混合持久化的 RDB 部分
- **AOF 日志** — 混合持久化的 AOF 部分
- **主从复制** — 全量复制依赖 RDB
- ← 返回 **持久化索引**