Redis 持久化策略(RDB / AOF / 混合持久化)详解(含选型与线上实践)
目标:把 Redis 持久化到底怎么选、怎么配、线上怎么排坑讲透。
你会得到:
- RDB / AOF 的原理与差异
- 配置项解释(save、appendonly、appendfsync、rewrite 等)
- 宕机丢数据窗口怎么算
- 性能影响与优化手段
- 最推荐的生产配置模板
目录
- [1. Redis 持久化的本质](#1. Redis 持久化的本质)
- [2. RDB:快照持久化](#2. RDB:快照持久化)
- [3. AOF:追加日志持久化](#3. AOF:追加日志持久化)
- [4. 混合持久化(RDB+AOF)](#4. 混合持久化(RDB+AOF))
- [5. 怎么选:场景选型表](#5. 怎么选:场景选型表)
- [6. 线上推荐配置模板](#6. 线上推荐配置模板)
- [7. 线上观测与排障清单](#7. 线上观测与排障清单)
- [8. 常见坑与最佳实践](#8. 常见坑与最佳实践)
- [9. 面试标准回答(1 分钟)](#9. 面试标准回答(1 分钟))
1. Redis 持久化的本质
Redis 是内存数据库,持久化就是回答两个问题:
- 我宕机后能恢复到什么程度?(丢数据窗口)
- 我付出多少性能成本?(写延迟、IO、fork、磁盘)
Redis 的三种持久化形态:
- RDB(Snapshot):定期把内存数据做成"快照文件"
- AOF(Append Only File):把写命令按顺序追加到日志文件
- 混合持久化:AOF rewrite 时用 RDB 作为基础,再追加增量 AOF
2. RDB:快照持久化
2.1 RDB 是什么
RDB = 某个时刻 Redis 内存数据的"快照"。
文件一般叫 dump.rdb(可配置)。
生成方式:
- 自动触发:
save规则满足时触发BGSAVE - 手动触发:
SAVE(阻塞)/BGSAVE(后台) - 复制场景:主给从全量同步时也会触发生成 RDB(或直接传输)
2.2 生成原理:fork + 写时复制(Copy-on-Write)
- Redis 主进程
fork()出子进程 - 子进程把内存数据写成 RDB 文件
- 主进程继续响应请求
- fork 的成本:会瞬间复制页表,内存大时 fork 可能变慢
- 写时复制:如果主进程在写入期间修改了某页,会触发复制该页(额外内存开销)
2.3 RDB 的优点
- 恢复快:RDB 是紧凑二进制,加载速度通常比 AOF 回放快
- 文件小:比 AOF 通常更省空间
- 对写性能影响相对可控:主要成本在 fork 和磁盘写快照
2.4 RDB 的缺点(你必须知道)
- 丢数据窗口大 :两次快照之间宕机,期间数据全丢
比如save 900 1,最坏可能丢 15 分钟 - fork/写盘对大内存实例可能造成延迟抖动(尤其是磁盘慢时)
2.5 RDB 配置
conf
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /var/lib/redis
还有一个很关键的安全项:
conf
stop-writes-on-bgsave-error yes
3. AOF:追加日志持久化
3.1 AOF 是什么
AOF 会把 Redis 的写命令(或者等价操作)追加到文件中(appendonly.aof)。
重启恢复时,Redis "回放" AOF 里的命令重建数据。
3.2 AOF 的丢数据窗口(核心看 appendfsync)
conf
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
always:每次写都 fsync(最安全,最慢)everysec:每秒 fsync(最常用,最坏丢 1 秒左右)no:交给 OS(最快,丢失不可控)
3.3 AOF 文件膨胀与重写(rewrite)
AOF 会越写越大,所以需要 AOF rewrite:
conf
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
AOF rewrite 的增量保证(简化):
- rewrite 期间新写入会进入 rewrite buffer
- 子进程写完后主进程把 buffer 追加到新 AOF
- 原子替换文件
3.4 AOF 的优缺点
优点:
- 丢数据窗口小(everysec)
缺点: - 恢复慢(回放)
- IO 压力持续
- rewrite/fork 也会抖动
4. 混合持久化(RDB+AOF)
conf
aof-use-rdb-preamble yes
AOF rewrite 时,新 AOF 文件的开头是 RDB 快照,后面是增量命令。
恢复时先加载 RDB 再回放少量 AOF,速度更快。
5. 怎么选:场景选型表
| 场景 | 推荐 |
|---|---|
| 纯缓存,允许丢 | RDB 或关闭持久化(谨慎) |
| 尽量少丢 | AOF everysec + 混合持久化 |
| 恢复速度要求高 | AOF everysec + aof-use-rdb-preamble |
| 写很少,追求极致不丢 | AOF always(一般不推荐) |
6. 线上推荐配置模板
6.1 通用稳妥(推荐)
conf
# RDB 兜底快照
save 900 1
save 300 10
save 60 10000
# AOF
appendonly yes
appendfsync everysec
no-appendfsync-on-rewrite yes
# AOF rewrite
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
# 混合持久化
aof-use-rdb-preamble yes
dir /var/lib/redis
6.2 纯缓存更轻(有风险)
conf
appendonly no
save 300 10
save 60 10000
风险:Redis 重启缓存全空,可能导致 DB 被回源打爆(雪崩)。
7. 线上观测与排障清单
bash
INFO persistence
关注:
rdb_last_bgsave_statusaof_enabledaof_rewrite_in_progressaof_current_size/aof_base_size
手动触发:
bash
BGSAVE
BGREWRITEAOF
8. 常见坑与最佳实践
- 大内存实例 fork 抖动:控制单实例内存、磁盘 IO、关闭 THP(常见建议)
- AOF 太大恢复慢:开启混合持久化 + 合理 rewrite 阈值
- 磁盘满导致持久化失败:监控磁盘;
stop-writes-on-bgsave-error默认 yes 更安全 - Sentinel/Cluster 不等于不丢:主从复制异步,failover 也可能丢最近写入,持久化仍重要
9. 面试标准回答(1 分钟)
Redis 持久化有 RDB 和 AOF。RDB 是定期快照,文件小恢复快但丢数据窗口大;AOF 记录写命令,
everysec最坏丢 1 秒,安全性更好但需要 rewrite 控制文件大小。Redis 4.0+ 支持混合持久化,rewrite 时用 RDB preamble 加速恢复,所以线上常用AOF everysec + aof-use-rdb-preamble yes,再配一定频率的 RDB 兜底。
一句话建议
- 生产默认:AOF everysec + 混合持久化(aof-use-rdb-preamble yes)
- RDB 做兜底,但别太频繁
- 重点关注 fork 抖动与磁盘 IO