Redis 7.0的BGREWRITEAOF不再fork子进程,因其采用Multi-part AOF架构:轻量子进程生成base.aof(或.base.rdb),主线程直接追加incr-*.aof,彻底移除aof_rewrite_buf缓冲区,消除COW内存翻倍与重写阻塞。

Redis 7.0 的 BGREWRITEAOF 不再 fork 子进程
旧版 Redis(6.x 及之前)执行 BGREWRITEAOF 时必须 fork 子进程,主进程内存越大,COW(Copy-on-Write)开销越恐怖——页表复制、内存碎片、OOM 风险都随之飙升。Redis 7.0 的 Multi-part AOF 彻底绕开了这个设计:它不再依赖单次全量快照生成一个大文件,而是把“生成 base”和“记录增量”拆开。子进程只负责轻量生成 base.aof 或 *.base.rdb,而所有新增命令由主线程直接写入 incr-*.aof 文件,全程不经过内存缓冲区。
aof_rewrite_buf 被物理移除,不是参数被废弃
很多人以为 aof_rewrite_buf_size 是个可配置项,其实它压根不存在于任何 Redis 版本中——这是个长期流传的误解。旧版真正存在的问题是 aof_rewrite_buf 这块无上限内存缓冲区:重写期间新命令同时追加到旧 AOF 和该缓冲区,高写入下极易暴涨数 GB,触发 OOM in aof_rewrite_buf 或 Failed to allocate rewrite buffer。Redis 7.0 直接删掉了这个缓冲区,不是调小它、限制它,是架构上不需要它了。所以你不会在 redis.conf 里看到相关配置,日志里也不会再刷出这类 OOM 提示。
appendfsync everysec 同步范围大幅缩小
在单文件 AOF 模式下,appendfsync everysec 每秒要刷整个 appendonly.aof 的累积内容,重写期间缓冲区膨胀会导致 fsync 延迟飙升。MP-AOF 下,它只同步当前正在写的那个 incr-*.aof 文件,通常只有几 MB 到几十 MB。这意味着:
- 每次
fdatasync()耗时更短、失败影响范围可控 - 即使某个
incr-*.aof损坏,启动时会被跳过,用前序base+ 其他有效incr恢复 - 不再有“重写结束前一次性追加缓冲区”的 I/O 尖峰
manifest 文件取代了单文件原子性依赖
旧版靠单个 appendonly.aof 文件名 + rename() 原子切换来保证安全;MP-AOF 改用 manifest 清单文件描述当前生效的 base.aof 和一串 incr-*.aof 文件顺序。这带来两个关键变化:
- 重写完成无需 rename 大文件,只需更新
manifest,毫秒级切换 - 文件结构松耦合,但要求
appenddirname必须显式配置且独立于dir,否则运维脚本可能误删incr-*.aof -
manifest格式错误(如Failed to load manifest.aof: invalid format)会导致启动卡死,不能靠改名绕过
真正容易被忽略的是:MP-AOF 不是“默认开启就自动生效”。如果 CONFIG GET aof-use-rdb-preamble 返回 yes,说明你实际走的是 6.x 混合模式,仍在用单文件 + aof_rewrite_buf;必须为 no,且目录下能看到 base.aof、incr-*.aof、manifest 三者共存,才算真正落地。











