AOF重写期间延迟飙升主因是磁盘I/O竞争,而非主线程阻塞;子进程批量写新AOF与主线程按策略刷盘共争磁盘带宽,导致IO排队、await升高、redis_aof_delayed_fsync持续非零。

重写期间主线程不阻塞,但IO竞争会让请求延迟明显升高——关键不是“能不能写”,而是“磁盘能不能及时吞下两路写入”。
为什么重写时延迟会突然上涨
AOF重写由子进程执行,主线程确实继续处理命令,但两者共用同一块磁盘设备:主线程持续追加新命令到 aof_buf 并按策略刷盘(appendfsync),子进程则在生成新AOF文件时批量写入大量数据。当磁盘I/O带宽或IOPS见顶,就会出现排队现象。
常见错误现象包括:latency doctor 报告 command latency 飙升、INFO commandstats 中 cmdstat_set 等耗时突增、监控里 redis_aof_delayed_fsync 指标持续非零。
- 不要只看CPU和内存——磁盘util > 90% 或 await > 20ms 就已是瓶颈信号
-
no-appendfsync-on-rewrite yes能缓解,但代价是重写期间宕机可能丢失最多1秒数据(取决于appendfsync everysec的窗口) - SSD的随机写性能远好于HDD,但若AOF文件和系统日志共用同一块盘,仍会互相干扰
启用 aof-rewrite-incremental-fsync 是最稳妥的调优动作
默认情况下,子进程在AOF重写时会攒够32MB才调一次 fdatasync,这容易造成单次刷盘压力过大,拖慢整个IO队列。开启增量同步后,每写入4MB(可配)就刷一次,把大IO打散成小IO,更利于调度。
实操建议:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 确认当前值:
CONFIG GET aof-rewrite-incremental-fsync,生产环境应为yes - 若磁盘I/O依然吃紧,可将写入批次从默认4MB调至8MB:
CONFIG SET aof-rewrite-incremental-fsync 8388608 - 该参数只影响子进程,不影响主线程的
appendfsync行为,无需担心一致性 - 注意:该配置不支持热重载,需写入
redis.conf并重启才永久生效
client-output-buffer-limit slave 设置不当会拖慢重写完成速度
很多人以为AOF重写缓冲区 aof_rewrite_buf 是独立可控的,其实它没有配置项能直接设大小;它的“积压程度”取决于子进程消费速度,而消费完的数据要发给从节点——如果从节点同步慢,主节点就得缓存更多待传播命令,间接卡住 aof_rewrite_buf 的清理节奏。
排查与调整:
- 检查从节点状态:
INFO replication中查看slave0的lag是否持续 > 10 - 调高从节点输出缓冲区上限:
CONFIG SET client-output-buffer-limit slave "256mb 64mb 60"(软限256MB、硬限64MB、超限60秒断连) - 避免把从节点部署在高延迟网络或低配机器上——这不是Redis配置能解决的问题
- 若无强一致性需求,可考虑临时关闭AOF重写期间的从同步:
CONFIG SET repl-diskless-sync no+repl-diskless-sync-delay 0,减少子进程额外负担
混合持久化(RDB+AOF)对重写性能的真实影响
开启 aof-use-rdb-preamble yes 后,重写不再纯靠解析命令重放,而是先fork出RDB快照,再追加增量命令。这大幅减少了子进程需要解析和序列化的命令量,尤其在key数量多、写操作频繁但最终状态稀疏的场景下效果显著。
但要注意:
- 首次启用该配置时,会触发一次完整重写,观察
INFO persistence中aof_last_bgrewrite_status是否为ok - RDB部分仍需全量写入磁盘,所以不能完全消除IO压力,只是把“解析+写”变成了“dump+追加”,整体耗时通常下降30%~50%
- 若业务存在大量过期key,RDB快照体积会比逻辑数据大,需配合
maxmemory-policy合理设置淘汰策略 - 该功能要求Redis ≥ 4.0,且AOF必须已开启,否则配置无效
真正容易被忽略的是:重写期间的 aof_buf 和 aof_rewrite_buf 是两个独立缓冲区,前者决定宕机丢失多少,后者决定重写能否顺利完成——它们的生命周期、刷盘时机、内存归属完全不同,混在一起看日志或监控很容易误判根源。


















