Redis 持久化机制
涵盖 RDB 快照、AOF 日志、AOF 重写机制、混合持久化,以及生产环境下的故障恢复策略。
RDB 与 AOF 对比
一、一句话结论
RDB是全量镜像、丢数据风险大;AOF逐条记录写指令、数据完整性更高,生产故障优先AOF恢复;混合持久化是4.0后最优方案。
二、RDB短板(为什么不能用来快速恢复业务)
1. 定时快照,必然丢失两次快照之间的数据
RDB触发:手动bgsave/配置定时策略save m n。
例:配置1小时生成一次RDB,宕机丢失近1小时全部写入数据,业务无法接受。
RDB是某一瞬间内存镜像,中间增量无落地。
2. bgsave全量fork子进程,生产不敢高频执行
bgsave调用fork()创建子进程,拷贝页表、占用CPU+内存:
- 大数据量fork耗时高、瞬时STW;
- 频繁RDB拖垮Redis性能,生产只能低频落地快照。
不能靠高频RDB来减少丢数据。
3. RDB文件损坏直接整库报废
RDB是单一二进制文件,磁盘坏块、落盘异常,整个RDB无法加载,全量数据报废。
三、AOF天然优势(生产恢复首选)
1. 落地粒度可控,最大限度少丢数据
AOF记录每一条写命令,三种刷盘策略:
appendfsync always:每条写立刻落盘,宕机0丢失(性能偏低,金融场景);appendfsync everysec:每秒刷一次磁盘(生产默认,最多丢1秒数据);no:交给OS缓冲区,丢数据不可控。
最多丢1s数据,远优于RDB动辄分钟/小时级丢失。
2. 恢复逻辑:重放指令,增量+全量全覆盖
AOF=顺序日志,Redis启动逐条回放日志还原数据,哪怕中间少量损坏,可手动裁剪异常命令,剩余数据正常恢复。
3. AOF文件可人工修复
文本格式日志,误删key、误执行flushdb,可以打开AOF删掉对应指令再恢复;RDB二进制看不懂,无法手动修正。
四、关键:Redis4.0+混合持久化(AOF内部嵌套RDB)
混合AOF结构:
文件前半段=RDB二进制全量快照 + 后半段=增量AOF日志
- AOF重写
bgrewriteaof时,先dump当前全量数据生成RDB写入AOF头部; - 重写之后新写入命令继续追加AOF。
兼顾两大优点:
- 恢复速度≈RDB(前半段RDB快速加载全量);
- 数据安全≈纯AOF(后半段增量日志不丢新数据);
现在生产标准配置:开启AOF+混合持久化,不靠独立RDB文件做日常恢复。
五、RDB真实生产定位(不是恢复,做备份)
RDB不作为宕机应急恢复,用途:
- 冷备份、异地归档:定期手动bgsave,把RDB传到异地机房做灾备;
- 主从初次全量同步:主库生成RDB传给从库初始化;
- 混合AOF内部使用,不单独落地文件。
AOF 重写机制详解
一、为什么需要AOF重写
问题根源
AOF持续追加每条写指令,同一个key多次修改会冗余大量命令:
set num 1
set num 2
set num 3
del num
原始AOF存4条指令;实际最终num已删除,重写后这条数据直接消失。
长期运行AOF文件无限膨胀:磁盘占满、重启回放AOF极慢。
AOF重写:根据当前内存真实数据生成最简指令,替换旧AOF,压缩体积。
二、重写触发两种方式
- 手动触发:bgrewriteaof(客户端命令)
- 自动触发:配置阈值
auto-aof-rewrite-percentage 100 # 当前AOF比上次重写后增大100%触发
auto-aof-rewrite-min-size 64mb # AOF最小64MB才允许自动重写
三、bgrewriteaof完整执行流程(fork子进程,无阻塞主线程)
- 主线程调用fork()生成子进程
子进程拥有内存数据快照(写时复制COW),主线程继续正常处理客户端命令,不阻塞业务。 - 子进程遍历全库数据,生成精简新AOF临时文件(aof.rewrite)
- String:只存最终set;
- List:批量rpush一次性写入;
- Hash:hmset批量;
- 过期/已删除key直接丢弃,不写入新日志;
只保留数据最终状态,删除中间冗余操作。
- 主线程开辟AOF重写缓冲区(aof_rewrite_buf)
fork之后主线程新收到的新增写命令:
- 正常追加到老AOF;
- 同时写入重写缓冲区(防止重写期间丢失增量数据)。
- 子进程写完临时新AOF,通知父进程
主线程把重写缓冲区全部内容追加到新临时AOF末尾。
这一步补齐fork之后新增的数据,保证新AOF数据完整。
- 原子替换文件:rename新文件覆盖旧AOF,重写结束。
关键:全程不阻塞Redis主线程
只有fork瞬间短暂STW(拷贝页表),大数据量fork会卡顿,是生产唯一隐患。
四、混合持久化关联(4.0+)
开启aof-use-rdb-preamble yes:
重写生成的新AOF头部是RDB二进制全量数据,尾部是增量AOF指令。
- 重启加载:先快速加载RDB全量,再回放尾部少量AOF,兼顾速度与安全;
- 没开混合:新AOF全是文本指令,文件偏大、启动回放慢。
五、生产三大踩坑点
- fork耗内存:fork瞬间复制页表,内存占用瞬时翻倍,物理内存不足触发swap、卡顿;
- 频繁自动重写:阈值配置过小,短时间多次fork压垮CPU;
- 磁盘IO打满:重写写新AOF+主线程同步刷旧AOF双写磁盘,IO飙升。
关联文档
- Redis 核心原理 — Redis 整体核心知识点
- Redis 基础 — Redis 基础知识