不会阻塞写操作,但可能显著拖慢写入延迟;重写期间读操作本身不被阻塞,但因cpu和i/o资源争抢会导致响应延迟上升。

重写期间写操作会阻塞吗
不会阻塞写操作,但可能显著拖慢写入延迟——尤其是当 aof_rewrite_buf 积压大量命令、或主进程追加缓冲区时发生同步刷盘(appendfsync always)或大块写入(如未启用 aof-rewrite-incremental-fsync)时。
常见错误现象包括:TIMEOUT、BUSY 响应,或监控中看到 latency 突增、used_memory_rss 快速上涨。
-
no-appendfsync-on-rewrite yes可缓解:它让重写期间跳过aof_buf的 fsync,但代价是最多丢 1 秒数据(依赖appendfsync everysec) - 若设为
no-appendfsync-on-rewrite no(默认),重写期间仍严格按appendfsync策略刷盘,高写入场景下易引发主线程等待 - 子进程 COW 机制会复制页表,写密集时内存占用可能翻倍,触发 OS OOM killer 风险
重写期间读操作受影响吗
读操作本身不被阻塞,但间接影响真实存在:CPU 和 I/O 资源被子进程大量占用,导致 redis-server 处理请求的响应时间上升,尤其在小规格机器或高并发读场景下明显。
典型表现是客户端观测到 P99 延迟跳升、instantaneous_ops_per_sec 波动剧烈,而非直接报错。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 子进程重写时需遍历全部 key,触发大量内存访问和磁盘顺序写(新 AOF 文件),与主线程争抢 CPU 缓存和 I/O 带宽
- 若使用
auto-aof-rewrite-percentage过低(如 50%),AOF 文件稍一增长就频繁重写,形成“重写风暴”,读写抖动持续发生 - Redis 8.2.3 中修复了 HyperLogLog 在重写期间的崩溃问题,旧版本遇到该结构高频写入时可能意外退出
为什么重写后 AOF 文件反而变大了
这不是 bug,而是重写逻辑与当前数据库状态不匹配的信号:重写基于内存快照生成最小命令集,若此时有大量过期 key 尚未被清理(lazyfree-lazy-eviction no)、或存在大量带过期时间但未触发删除的 key,重写结果会包含这些冗余状态。
更隐蔽的原因是:重写过程中新写入的命令(如 EXPIRE、SET 带 EX)被追加进 aof_rewrite_buf,最终全量落盘,而旧 AOF 中对应 key 可能已被后续 DEL 覆盖——但新文件没机会做等价压缩。
- 检查
info keyspace中各 db 的expires数量,若远高于实际活跃 key 数,说明过期 key 淤积 - 确认是否启用了
active-defrag-ignore-bytes或active-defrag-threshold-lower,内存碎片高时重写可能写出更多碎片化指令 - 避免在重写期间执行大批量
SET+EXPIRE组合操作,这类模式极易破坏重写压缩效果
如何安全地触发 BGREWRITEAOF
不要在业务高峰手动执行 BGREWRITEAOF,也不依赖默认自动策略无脑运行;关键在于控制节奏与资源隔离。
真正起作用的不是“要不要重写”,而是“什么时候重写、用什么资源重写、重写失败怎么兜底”。
- 把
auto-aof-rewrite-min-size设为至少 1GB(小实例除外),避免小文件频繁重写;auto-aof-rewrite-percentage建议调高至 100–200%,留出缓冲空间 - 生产环境必须开启
aof-rewrite-incremental-fsync yes(默认),否则子进程攒满整个新文件才刷盘,崩溃即前功尽弃 - 监控
aof_current_size和aof_base_size差值,结合used_memory_peak判断重写时机——内存峰值刚回落时触发最稳妥 - 重写失败后 Redis 不会自动重试,需靠外部脚本监听
CONFIG GET aof_last_bgrewrite_status并告警
no-appendfsync-on-rewrite 和 appendfsync 的协同关系——前者只管“重写时跳过刷盘”,后者才决定“平时最多丢多久”,两者配错,故障窗口就从秒级扩大到分钟级。










