AOF重写期间淘汰加剧是因为fork后主线程双写缓冲区推高used_memory_rss,触发maxmemory实时淘汰;需联动调低auto-aof-rewrite-percentage(如>0.7水位时设60~80)、预留15%内存余量、启用lazyfree-lazy-eviction并避开写高峰。

必须把 maxmemory 余量和 auto-aof-rewrite-percentage 联动调,否则重写一启动,evicted_keys 就会跳着涨。
为什么AOF重写期间淘汰会突然加剧
重写本身不触发淘汰,但会放大内存压力:子进程 fork 后,主线程继续接收写请求,同时往旧 AOF 缓冲区和 aof_rewrite_buffer 双写;这两个缓冲区都吃 used_memory_rss,而 Redis 的淘汰策略(如 allkeys-lru)是实时生效的——只要 used_memory_rss 超过 maxmemory,立刻开始驱逐。
常见现象包括:INFO memory 中 evicted_keys 在 aof_rewrite_in_progress 为 1 后 2–3 秒内突增、used_memory_rss > 1.8 × used_memory、mem_fragmentation_ratio 同步爬升超过 1.5。
- 别只盯着
used_memory:它不包含 AOF 缓冲和 COW 复制页,OOM killer 和淘汰逻辑实际看的是used_memory_rss -
no-appendfsync-on-rewrite yes只能缓解磁盘 IO,对内存占用和淘汰无影响 - Redis 6.2 默认未开启
lazyfree-lazy-eviction,淘汰是同步阻塞的,加剧延迟毛刺
怎么配 auto-aof-rewrite-percentage 才不拉爆淘汰
这个值不能孤立调,得看当前内存水位。默认 100 在写密集场景下极易踩雷——AOF 刚涨到上次重写大小的两倍,主线程可能已经逼近 maxmemory 上限。
- 如果
used_memory / maxmemory > 0.7,立即将auto-aof-rewrite-percentage降到 60~80 - 用
allkeys-lfu策略可放宽至 90:LFU 淘汰更平滑,对突发写包容性更强 - 绝对不要设为 0:那等于禁用自动重写,AOF 文件持续膨胀,恢复时间不可控,
redis-check-aof也更容易失败 - 配合
auto-aof-rewrite-min-size调整:≤4GB 实例可设 16mb,≥16GB 实例建议 ≥64mb,避免小文件高频重写
重写期间如何抑制淘汰抖动
核心是给内存留出“安全缓冲”,而不是指望重写过程不占内存。
- 预留至少 15%
maxmemory余量:比如总内存 16GB,maxmemory设 12GB,而非 13.5GB - 手动在低峰期执行
BGREWRITEAOF,避开业务写高峰,减少重写缓冲区堆积 - 启用
lazyfree-lazy-eviction yes(6.2 支持):让淘汰 key 的释放异步化,降低主线程阻塞 - 监控
aof_rewrite_buffer_length:若该值持续 > 10MB,说明重写缓冲增长过快,需检查是否有批量HSET、DEL或大 key 修改
真正容易被忽略的是:重写不是“一次性的内存开销”,而是从 fork 开始就持续施压的过程。缓冲区大小随写入线性增长,COW 页复制又不可预测——所以不能只靠调百分比,得把 maxmemory、写入节奏、淘汰策略三者绑在一起看。











