
为什么 bgrewriteaof 会突然拉高 CPU?
因为 AOF 重写是子进程做的,但父进程要持续向重写缓冲区(aof_rewrite_buf_blocks)拷贝新写命令——这个拷贝是同步、阻塞式的,且在每次事件循环中反复执行。当写入流量大、命令短小密集(如大量 INCR、SET),拷贝开销就直接反映为 CPU 占用飙升。
常见错误现象:top 显示 redis-server 进程 CPU 持续 90%+,INFO persistence 中 aof_rewrite_in_progress:1 且 aof_current_rewrite_time_sec 长时间不归零;同时客户端明显延迟升高。
- 别在高峰期手动触发
bgrewriteaof,尤其写入 QPS > 5k 的实例 - 检查是否启用了
auto-aof-rewrite-percentage但auto-aof-rewrite-min-size设得太小(如1mb),导致每几分钟就重写一次 - 确认没有多个后台任务并发:AOF 重写和 RDB
save不能同时进行,若配置了save 60 10000又频繁写入,可能因等待 RDB 结束而堆积重写请求
如何安全调低 AOF 重写频率?
核心不是“禁用”,而是让重写真正符合业务节奏:既避免太勤(CPU 压力),又防止太大(重写耗时长、失败风险高)。
使用场景:写入量稳定、日增 AOF 文件约 200MB 的集群节点;或压测中发现重写后平均延迟从 0.3ms 涨到 8ms。
- 把
auto-aof-rewrite-percentage从默认100提高到200或300(即 AOF 增长 2–3 倍才触发) -
auto-aof-rewrite-min-size至少设为64mb,避免小文件频繁重写;若日均增长500mb,可设为256mb - 确保
aof-rewrite-incremental-fsync为yes(默认),它会让子进程每写 32MB 就刷一次磁盘,降低单次 I/O 压力
no-appendfsync-on-rewrite yes 真的能救 CPU 吗?
它只影响父进程在重写期间是否暂停 fdatasync,对命令拷贝本身无任何缓解作用。开启后,AOF 日志落盘被延迟,极端情况下可能丢失最多 1 秒数据(取决于 appendfsync 设置)。
性能影响:CPU 使用率几乎不变,但磁盘写入毛刺更平滑;兼容性上,所有 Redis 2.8+ 都支持,但若业务要求强持久化(如金融类事务日志),此选项不可用。
- 仅在
appendfsync everysec且允许秒级数据丢失时启用 - 绝对不要在
appendfsync always下设为yes——配置冲突,Redis 启动会报错:ERROR: Invalid argument for config 'no-appendfsync-on-rewrite' - 观察
INFO stats中aof_delayed_fsync计数,若持续增长,说明磁盘已成瓶颈,该调的是 I/O 而非这个开关
后台任务排队卡住怎么办?
Redis 后台任务(RDB save / AOF rewrite)是单队列串行执行的。如果一个重写卡住(比如磁盘满、OOM Killer 杀掉子进程),后续所有重写请求都会挂起,aof_rewrite_scheduled 会持续为 1,而 aof_rewrite_in_progress 为 0。
典型错误信息:Failed to rewrite the AOF file: No space left on device 出现在 redis.log,但 INFO persistence 不显示重写进行中。
- 立即清理磁盘空间,然后执行
CONFIG SET auto-aof-rewrite-percentage 0临时禁用自动触发 - 用
DEBUG SLEEP 0.1强制推进事件循环,再查aof_rewrite_scheduled是否归零;若仍为 1,需重启实例(这是唯一清空调度状态的方式) - 监控项必须包含:
aof_rewrite_scheduled+aof_current_size_mb+used_memory_rss,三者联动才能预判排队风险
最麻烦的其实是重写中途子进程被系统杀掉却没及时通知父进程——这种静默失败不会报错,只会让调度状态僵死。所以磁盘空间、内存余量、vm.overcommit_memory 设置,一个都不能松懈。


















