Redis 有两种持久化机制:

RDB

RDB 持久化方式会在一个特定的间隔保存那个时间点的一个数据快照

AOF

AOF 持久化方式则会记录每一个服务器收到的写操作。在服务启动时,这些记录的操作会逐条执行从而重建出原来的数据。写操作命令记录的格式跟 Redis 协议一致,以追加的方式进行保存

Redis 的持久化是可以禁用的,就是说你可以让数据的生命周期只存在于服务器的运行时间里。两种方式的持久化是可以同时存在的,但是当 Redis 重启时,AOF 文件会被优先用于重建数据。

RDB/AOF 的定义与”重启优先 AOF”的规则正确,但生产决策还需要四层细节:RDB 的 fork-COW 机制与代价、AOF 三种刷盘策略与重写、混合持久化、以及故障恢复的取舍矩阵。本文补全。

RDB:快照的 fork + 写时复制

  • 触发:save(阻塞,禁用)/ bgsave(后台)/ 配置 save 900 1 等阈值 / 主从全量同步
  • 机制:主进程 fork 子进程,子进程共享父进程内存页(COW copy-on-write):父进程继续服务写请求,写到某页时才复制该页——快照是 fork 时刻的一致性视图
  • 代价:fork 瞬间的延迟(页表越大越慢,GB 级内存毫秒到几十毫秒);COW 期间内存峰值可达 2 倍(写密集时大量页被复制)
  • 优点:文件紧凑、恢复快(直接加载二进制)、适合备份/全量同步
  • 缺点:两次快照间的数据全丢(分钟级窗口)

AOF:追加日志与刷盘策略

  • 每条写命令追加到 aof 缓冲区,按策略刷盘:
    • appendfsync always:每命令 fsync——最安全(丢 0 条),性能最差
    • appendfsync everysec(默认):每秒 fsync——最多丢 1 秒,性能与安全平衡点
    • appendfsync no:交给 OS 刷盘——最快,丢多少看 OS 心情(可能 30s)
  • AOF 重写(rewrite):文件无限增长不可接受;重写=不读旧文件、以当前内存数据为准生成最小命令集(fork 子进程 dump),期间新写命令进重写缓冲区追加保证不丢;bgrewriteaof 手动或 auto-aof-rewrite-percentage 自动触发
  • 优点:丢失窗口小(秒级)、文本协议可读可审计(误操作可人工剔除命令恢复)
  • 缺点:文件大、恢复慢(重放命令)

混合持久化(4.0+ 默认推荐)

rewrite 时产出”RDB 全量快照 + 增量 AOF 命令“的混合格式:恢复时先加载 RDB(快)再重放增量 AOF(丢得少)——兼得两者优点,今天的新部署默认形态(aof-use-rdb-preamble yes)。

重启恢复规则与校验

  • 两者皆开:优先 AOF(数据更全)
  • AOF 损坏:redis-check-aof –fix 修复(截断尾部不完整命令)
  • RDB 加载失败且 AOF 关闭:启动失败(防脏数据静默上线的保护设计)

取舍矩阵与生产配置

需求 配置
纯缓存、可全丢 关闭持久化(或仅 RDB 便于重启预热)
缓存+容忍分钟级丢失 RDB(save 阈值)
容忍秒级丢失(多数业务) AOF everysec + 混合重写
最小丢失 AOF always(接受性能代价)或主从+哨兵/集群多副本
备份/迁移 RDB 文件拷贝(配合 replica 离线备份)

重要认知:持久化≠高可用。RDB/AOF 解决”重启不丢”,不解决”节点宕机期间服务可用”——后者靠主从复制+哨兵/Cluster。丢数据容忍度与可用性要求是两个独立维度,分别用持久化策略与副本拓扑回答。

运维要点

  • bgsave/rewrite 的 fork 延迟监控(info persistence 的 latest_fork_usec);大内存实例考虑透明大页关闭(THP 会放大 fork 代价)
  • AOF 文件与 RDB 文件异机备份(同机备份防不了磁盘故障)
  • 误操作恢复演练:AOF 剔除误命令重放 / RDB 时间点恢复——没演练过的恢复方案等于没有

Redis 持久化 = RDB(fork+COW 快照,快但窗口大)+ AOF(追加日志,窗口小但重放慢)+ 混合持久化(两者合体)三形态;选型先定”能丢多少”,再定”恢复要多快”,最后用副本拓扑补可用性——三个问题答完,配置自然唯一。