Redis 持久化:RDB、AOF 与恢复目标(八)
把内存治理讲清以后,下一步就该单独回答另一个问题:Redis 里的数据故障后要怎么回来。这篇只讲持久化与恢复,不再混入 TTL、淘汰和碎片率。
系列导航:
- 上一篇:Redis 内存治理:TTL、淘汰策略、碎片与大 Key(七)
- 当前篇:Redis 持久化:RDB、AOF 与恢复目标(八)(本文)
- 下一篇:Redis 主从复制与 Sentinel:从复制链路到自动故障切换(九)
持久化先回答恢复目标,不要先背参数
讨论 Redis 持久化时,最容易犯的错是先问“该不该开 AOF”,却没有先回答两个更关键的问题:
- 业务最多能接受丢多少数据,也就是
RPO。 - 业务最多能接受多久恢复,也就是
RTO。
如果这两个目标不清楚,后面的 save、appendonly、appendfsync 往往只是照抄模板。因为 Redis 的持久化从来不是“开了就安全”,而是“你愿意为多小的丢失窗口和多快的恢复速度付出多少写入、磁盘和运维成本”。
一个最常见的判断框架是:
- 纯缓存:重点是尽快恢复服务,通常不需要为非常严格的
RPO付出高成本。 - 可重建状态:可以接受一定丢失,但恢复过程不能太慢。
- 关键在线状态:既希望少丢,又要求恢复快,就必须把持久化、复制和演练一起设计。
RDB 解决“某个时间点的整体快照”
RDB 的语义很直接:在某个时间点把当前数据集压成一份快照文件。它特别适合三类事情:
- 周期性备份。
- 重启后快速装载一份完整数据集。
- 为复制初始化、迁移或离线分析提供基线数据。
如果主库需要向一个新副本做全量同步,底层也是先准备一份当下数据集的快照,再把快照后的增量写命令补过去。也正因为如此,RDB 的优点和代价都很明确:
- 优点是文件紧凑、恢复通常更快。
- 代价是两次快照之间的写入天然存在丢失窗口。
例如:
save 900 1
save 300 10
save 60 10000
这类配置表达的是“满足这些写入条件时,就生成一份新快照”。它不是持续日志,所以你不能指望 RDB 把最后一秒内的所有写入都精确保住。
AOF 解决“把写路径连续记录下来”
AOF 的思路不同。它不是保存一个静态瞬间,而是把写命令按顺序追加下来,让 Redis 在恢复时通过重放这些命令尽量逼近故障前的状态。
最常见的生产起点通常像这样:
appendonly yes
appendfsync everysec
这里最关键的是 appendfsync:
always:每次写命令都刷盘,安全性最保守,但写入代价最高。everysec:通常每秒刷盘一次,是很多生产环境的现实折中。no:刷盘完全交给操作系统,性能开销更低,但丢失窗口更难控制。
AOF 的核心价值在于把 RPO 压得更细,但代价也很直接:
- 写路径会承受额外 I/O。
- 文件会持续增长。
- 恢复速度会受到日志体积影响。
所以 AOF 不是“绝对优于 RDB”,而是“在你关心更小数据丢失窗口时,更有价值”。
混合持久化解决“既要恢复快,又不想日志无限膨胀”
如果只开 RDB,恢复窗口比较粗;如果只依赖 AOF,文件会长期膨胀,恢复也可能越来越慢。混合持久化的意义,就是把两种能力拼在一起。
Redis 常见的做法是开启 AOF,同时让重写后的 AOF 前半段以 RDB preamble 的方式保存一份紧凑快照,再在后面接上最近的增量写命令。常见配置形态类似:
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
你可以把它理解成:
- 基线数据用快照方式保存,装载更快。
- 最近增量继续用 AOF 命令补齐,丢失窗口更小。
- AOF 重写负责把越来越长的历史命令重新收敛成“恢复当前状态真正需要的内容”。
这也是很多生产环境最终采用的组合路径:不是在 RDB 和 AOF 之间二选一,而是把它们放进同一套恢复设计里。
恢复目标会反过来决定你的持久化组合
把 RPO 和 RTO 放回来看,很多配置选择就不再抽象:
- 如果
RPO很宽松,纯缓存实例可能只保留轻量快照,甚至更依赖重建而非持久化。 - 如果
RPO很严格,就不能只靠间隔较长的RDB,通常要引入AOF或混合持久化。 - 如果
RTO很严格,你就不能只想着“尽量少丢”,还得控制恢复时要回放的日志规模,并实际演练恢复耗时。
真正决定配置的,不是“Redis 推荐开哪个”,而是“业务愿意接受什么损失、团队能承受什么写入开销、故障时是否有明确恢复流程”。
恢复不是配置项,而是一条演练过的路径
很多团队把持久化做成了“配置存在”,却没有把恢复做成“流程存在”。真正上线前至少要确认:
- 故障后优先从哪份数据恢复,是
RDB、AOF还是重建。 - AOF 文件规模是否长期可控,重写是否在正常发生。
- 恢复后的数据校验怎么做,哪些业务指标说明服务真的回来了。
- 备份文件是否可获取、可校验、可在隔离环境实际加载。
如果这些问题没有演练过,那么“我已经开启持久化”在故障当天的价值其实很有限。
一套够用的持久化选型起点
如果你需要一个足够实用的起点,可以先按下面方式判断:
- 纯缓存:先想清楚是否真的需要恢复 Redis 本身,而不是直接由上游重建。
- 一般在线状态:保留
RDB基线,同时结合AOF everysec或混合持久化,通常更平衡。 - 恢复要求更高:把
AOF、重写频率、磁盘能力、备份保留和恢复演练一起纳入方案,而不是只调一个参数。
记住一个最重要的原则:持久化的目标不是“让 Redis 看起来更像数据库”,而是让你在故障发生后,能以可接受的数据损失和时间成本把服务真正恢复回来。
本篇解决了什么:
- 说明了为什么讨论持久化前要先明确
RPO与RTO - 拆清了
RDB、AOF、混合持久化和恢复演练各自负责什么 - 把持久化选择从“抄配置模板”拉回到真实恢复目标