aof重写会阻塞主线程,根本原因是fork()系统调用需复制页表并受copy-on-write机制影响,内存越大、脏页越多,fork耗时越长,导致主线程卡顿;备库执行aof重写可规避该问题,实现主库轻量rdb+备库承担aof的高可用分工。

主库开启AOF重写会触发fork阻塞
Redis执行BGREWRITEAOF时,必须fork子进程来遍历内存数据并生成新AOF文件。主库本身承担全部写流量,fork瞬间会复制当前页表(虽用写时复制,但仍有开销),若内存占用大(比如20GB+),fork耗时可能达百毫秒级——这期间主线程卡住,INFO stats中latest_fork_usec飙升,客户端超时频发。
常见错误现象:主库QPS正常但延迟毛刺明显、redis-cli --latency显示p99跳变到50ms以上、从库同步延迟突然增大。
- 主库配置
auto-aof-rewrite-percentage 100+auto-aof-rewrite-min-size 64mb极易在写入高峰自动触发重写 - 重写期间主库仍持续追加旧AOF,导致
aof_current_size暴涨,可能反复触发连锁重写 - 即使设
no-appendfsync-on-rewrite yes,也只缓解fsync压力,无法消除fork开销
备库重写更安全,但需显式启用AOF
备库不处理写请求,BGREWRITEAOF的fork和序列化全程不影响线上服务。更重要的是,重写后的新AOF文件可直接用于故障切换后的主库启动恢复——这是它比RDB更可靠的兜底依据。
关键点在于:备库必须明确开启AOF,且不能依赖主库同步来的AOF内容(主从不传输AOF文件)。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 备库
redis.conf中必须设appendonly yes,否则BGREWRITEAOF无效 - 验证是否生效:
redis-cli -p 6380 info persistence | grep aof_rewrite,确认aof_rewrite_in_progress:0且aof_last_rewrite_status:ok - 主库应设
appendonly no,避免AOF与RDB双持久化带来的双重写放大
主库只用RDB + 备库接管AOF是生产标配
这不是功能取舍,而是把成本分配到非关键路径:RDB快照由主库异步完成(bgsave),AOF重写由备库承担。两者分工后,主库CPU/IO压力下降明显,尤其在高吞吐写入场景下。
典型配置差异:
- 主库
redis.conf:注释所有save行(或仅留save ""),appendonly no,stop-writes-on-bgsave-error yes - 备库
redis.conf:保留save 300 10等RDB兜底策略,同时设appendonly yes、appendfsync everysec - 切勿让主库和备库都开启AOF——
aof_current_size膨胀、重写频率失控、磁盘IO饱和三者会互相加剧
为什么“不建议开启”不是“绝对禁止”
某些低QPS、小内存(fork()系统调用的隐蔽开销。
最容易被忽略的是:主从切换后,原备库升主,若它之前没启用AOF,新主库就失去AOF兜底能力;而如果原主库AOF一直开着,切换后又面临重写阻塞的老问题。这种状态漂移比配置错误更难定位。










