说明磁盘io已饱和,但redis主线程尚未被直接卡死——它还在往aof缓冲区追加命令,只是后台fsync线程和重写子进程都在争抢磁盘带宽。

Redis AOF重写时iostat看到%util=100%但Redis没报错,说明什么
说明磁盘IO已饱和,但Redis主线程尚未被直接卡死——它还在往AOF缓冲区追加命令,只是后台fsync线程和重写子进程都在争抢磁盘带宽。此时redis-cli info persistence里aof_delayed_fsync很可能持续大于0,aof_last_fsync_time_sec飙升,而SLOWLOG和INFO commandstats可能完全正常,因为延迟发生在内核IO层,Redis进程本身无感知。
常见误判是以为“没报错=没问题”,其实系统已进入亚健康状态:
- MySQL、日志采集等共用磁盘的服务开始超时
- 哨兵检测到主节点响应变慢,触发误切换
- 新写入命令在缓冲区堆积,内存占用悄悄逼近
maxmemory
如何确认AOF重写正在吃掉磁盘IO
不能只看iostat -x 1的总值,要联动日志和指标交叉验证:
- 查Redis日志:出现
Starting automatic rewriting of AOF或Background AOF rewrite finished successfully即为AOF重写 - 查配置:
redis-cli config get auto-aof-rewrite-percentage和auto-aof-rewrite-min-size,若两者都未禁用,且当前aof_current_size>aof_base_size× 阈值,重写随时会触发 - 盯
iostat -x -d /dev/sdb 1(指定Redis数据盘):若wkB/s稳定在20–50MB/s、%util持续95%+、await> 30ms,基本可锁定是AOF重写 - 注意:
wkB/s数值远大于aof_current_size差值——因为含文件系统元数据、对齐填充、日志开销
no-appendfsync-on-rewrite yes真能解决问题?
它能缓解主线程卡顿,但代价是重写期间所有新写入不落盘。如果此时Redis崩溃,最近1秒(appendfsync everysec)+整个重写窗口期的数据全部丢失。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
是否启用,取决于业务容忍度:
- 适用场景:非核心计数器、实时性要求低的统计类数据
- 必须配套动作:
CONFIG SET appendfsync everysec(不能是always),并监控aof_rewrite_in_progress避免重写拖太久 - 更稳妥做法:先调大重写阈值,比如
CONFIG SET auto-aof-rewrite-percentage 200+CONFIG SET auto-aof-rewrite-min-size 2gb,减少重写频次
为什么RDB和AOF重写同时发生会雪崩
两者都依赖fork(),但行为不同:
- RDB是短时高压:
fork后子进程一次性dump,iostat看到几秒内wkB/s拉满后归零;日志有Background saving started by pid - AOF重写是中时长稳定IO:持续几十秒到几分钟,
wkB/s波动小但高位持续 - 当两者叠加,
fork带来的COW内存开销翻倍,磁盘IO队列深度暴涨,await从30ms跳到100ms+,系统级排队开始——这时连接超时、哨兵误切、从库同步断开就全来了
最隐蔽的点:很多团队只关了RDB(save ""),却忘了AOF重写仍在默默运行,且更容易被监控遗漏。










