Redis 6.0 的 AOF 重写默认仍为单线程,因需保证数据一致性,避免并发遍历导致读取中间态;优化依赖 aof-rewrite-incremental-fsync、aof-use-rdb-preamble 和 fork 性能调优。
Redis 6.0 的 AOF 重写为什么默认还是单线程?
Redis 6.0 确实引入了多线程 I/O(io-threads),但仅用于处理网络读写,bgrewriteaof 过程本身仍由主线程串行执行。AOF 重写本质是「遍历所有键、序列化为命令、写入新 AOF 文件」,涉及大量内存访问和磁盘 I/O,而 Redis 主线程必须保证数据一致性,不能把 key 遍历和命令生成交给子线程并发做——否则可能读到中间态数据(比如正在被 set 修改的 hash 结构)。
真正能提速 AOF 重写的三个关键配置
虽然重写逻辑本身没多线程化,但 Redis 6.0 通过三项底层优化显著降低耗时:
-
aof-rewrite-incremental-fsync:默认yes,让重写过程每写入 32MB 就调用一次fdatasync(),避免最后一次性刷盘卡顿;关掉它反而可能导致重写后期阻塞超 1 秒 -
aof-loading-process不影响重写,但注意:如果启用了aof-use-rdb-preamble(默认yes),重写会先 fork 出 RDB 快照,再追加增量命令——这比纯 AOF 重写快得多,因为 RDB 序列化更紧凑、CPU 开销更低 -
auto-aof-rewrite-percentage和auto-aof-rewrite-min-size要合理设置,避免频繁触发小重写;例如设为100和64mb,比默认的100+64mb更稳(注意:64mb 是字面值,不是 64MB 内存)
fork() 阶段卡顿比重写本身更值得优化
用户感知的「AOF 重写慢」,80% 实际是 fork() 耗时长导致的——尤其在大内存实例(>10GB)+ 使用了 transparent_hugepage 的 Linux 上。此时主线程会停顿,表现为 INFO stats 中 latest_fork_usec 达到数百毫秒甚至秒级。
- 关闭 THP:
echo never > /sys/kernel/mm/transparent_hugepage/enabled(需 root,重启失效) - 升级内核至 4.14+,启用
copy-on-write优化(Redis 6.0+ 自动检测) - 避免在重写前刚执行过
debug reload或大量set,这类操作会让 page table 更复杂,加剧 fork 延迟
替代方案:RDB+AOF 混合模式是否真更快?
开启 aof-use-rdb-preamble yes 后,bgrewriteaof 实际执行的是「fork → 生成 RDB 片段 → 追加自上次重写以来的 AOF 命令」。实测在 8GB 数据集上,比纯 AOF 重写快 3–5 倍,且 fork 时间减少约 40%(因 RDB 写入更少页)。
Slazzer
免费在线抠除图片背景
下载
但要注意:RDB 部分不支持带过期时间的 key 的精确时间戳还原(会降级为 PEXPIREAT),如果业务强依赖毫秒级过期精度,需权衡。
真正容易被忽略的是:混合模式下,AOF 文件头会包含 RDB 格式二进制块,redis-check-aof --fix 无法修复这种文件——出问题只能靠 redis-check-rdb 配合人工拼接。