AOF重写卡业务的根本原因不是重写本身阻塞主线程,而是fork()暂停主线程及重写与主线程双重IO竞争导致磁盘队列堆积、内核延迟升高;需通过错峰调度、启用no-appendfsync-on-rewrite yes、协同调整auto-aof-rewrite-min-size与percentage等措施缓解。

为什么AOF重写会卡业务?不是因为重写本身,而是fork和IO抢资源
重写过程由子进程执行,不阻塞主线程,但fork()系统调用在内存大(比如 >16GB)时会暂停主线程几百毫秒;更关键的是,重写期间主线程仍持续写入新命令到aof_buf,而子进程重写又在刷盘,双重IO压力会让磁盘队列堆积,触发内核延迟,最终表现为客户端延迟飙升、超时增多。
常见错误现象:INFO persistence里aof_rewrite_in_progress为1的同时,used_memory_rss比used_memory高30%以上,且latency event中出现大量command或fast-command尖峰。
- 检查是否真在重写:运行
redis-cli info persistence | grep -E "(aof_rewrite|aof_current_size|aof_base_size)" - 确认内存是否已开始swap:
cat /proc/$(pidof redis-server)/status | grep VmSwap,非零值即危险 - 避免在高峰期自动触发:用
CONFIG SET auto-aof-rewrite-percentage 0临时关闭自动重写,改用redis-cli BGREWRITEAOF手动调度到低峰
no-appendfsync-on-rewrite yes必须开,但得接受2秒数据丢失风险
这个配置的作用是:当aof_rewrite_in_progress为1时,跳过appendfsync everysec的定时刷盘,把所有待同步数据暂存在aof_buf里,等重写结束再集中刷。它能直接砍掉50%以上的磁盘IO竞争,实测可将P99延迟从800ms压到120ms以内。
但它只对appendfsync everysec生效;若设为always,该配置无效;若设为no,则本就无定时刷盘,也无需开启。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 生产环境推荐组合:
appendfsync everysec+no-appendfsync-on-rewrite yes - 金融类强一致性场景慎用:重写失败(如磁盘满)时,最多丢失重写开始后2秒内的写入
- 验证是否生效:重写期间执行
redis-cli CONFIG GET no-appendfsync-on-rewrite,返回yes且INFO stats中aof_delayed_fsync值稳定增长,说明起效
auto-aof-rewrite-min-size和auto-aof-rewrite-percentage要一起调,不能只动一个
单独把auto-aof-rewrite-percentage从100调到150,看似拉宽了触发条件,但如果auto-aof-rewrite-min-size还卡在默认64mb,那只要AOF涨到192mb(64mb × 3)就又触发了——实际只撑了128mb增长空间,毫无意义。
真正压峰的逻辑是:让两次重写之间的绝对增长量变大。比如目标是每次重写间隔至少撑住500MB增长,那就得同时满足:auto-aof-rewrite-min-size 256mb + auto-aof-rewrite-percentage 100(即256mb → 512mb才触发)。
- HDD环境建议:
auto-aof-rewrite-min-size 256mb+auto-aof-rewrite-percentage 120 - SSD + 写入QPS >10k:可设
auto-aof-rewrite-min-size 128mb+auto-aof-rewrite-percentage 80,用更频繁但更轻量的重写换IO平滑 - 切忌热更新后不观察:
CONFIG REWRITE保存配置,但需等下一次重写完成,INFO persistence里的aof_base_size才会更新为新基准值
重写期间CPU飙高别急着调参,先看是不是子进程被IO卡住
Redis重写子进程本身是CPU密集型,但实测中90%的“CPU高”其实是iowait伪装的——top里看到redis子进程%CPU高,但pidstat -u -p $(pgrep -f "redis.*aof") 1显示%iowait >60%,说明它在等磁盘返回,不是真算力瓶颈。
这时调高auto-aof-rewrite-percentage只会让下次重写更晚、文件更大、IO压力更集中,反而恶化问题。
- 优先动作:用
iostat -x 1盯%util和await,若%util持续>95%或await>20ms,说明磁盘已饱和 - 紧急缓解:把AOF文件路径挪到另一块空闲SSD,用
CONFIG SET dir /data-ssd+CONFIG SET appendfilename appendonly.aof(注意需提前建好目录) - 长期方案:重写期间禁用其他后台任务,比如停掉
redis-cli --rdb离线备份,避免多进程争IO
aof_base_size这个基准值一旦因失败未更新,后续所有自动触发都可能误判——每次重写前务必确认INFO persistence里aof_last_bgrewrite_status是ok。


















