redis磁盘io瓶颈需结合iostat与info指标交叉验证:%util>90%、await>50ms或avgqu-sz>2表明磁盘真实过载;aof_delayed_fsync上升但%util低则多因dirty_ratio过小导致内核频繁同步。

Redis 本身不暴露磁盘 IO 负载,必须靠系统级工具交叉验证;单看 INFO persistence 里的 aof_delayed_fsync 或 rdb_last_bgsave_time_sec 上升,不能直接断定是磁盘瓶颈——它可能是内核回写策略、page cache 压力或 Redis 配置失配导致的假信号。
iostat -x 1 是第一道筛子:盯住 %util、await 和 svctm
Redis 持久化(bgsave 或 bgrewriteaof)一旦触发,就会产生真实写盘行为。此时用 iostat -x 1 持续观察目标磁盘(比如 sda 或 nvme0n1):
-
%util > 90%持续超过 5 秒,说明磁盘队列已满,物理层确实在排队 -
await > 50ms(机械盘可放宽到 100ms,但 NVMe 应该 -
svctm已被内核废弃,别信;重点看avgqu-sz(平均队列长度)是否长期 > 2 —— 队列深了,线程再多也白搭 - 注意区分设备名:如果用 LVM 或 RAID,要查到底层物理盘(
lsblk -d -o NAME,ROTA,TYPE看 ROTA=0 才是 SSD/NVMe)
对比 Redis 持久化指标:aof_delayed_fsync 和 rdb_last_bgsave_time_sec
运行 redis-cli info persistence | grep -E "aof_delayed_fsync|rdb_last_bgsave_time_sec",结合 iostat 实时输出做归因判断:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
aof_delayed_fsync持续上升 +iostat显示%util高 → 很可能磁盘真的慢,fsync 被阻塞 -
aof_delayed_fsync上升但%util只有 30%~40% → 问题不在磁盘,而在内核 page cache 回写太激进(检查/proc/sys/vm/dirty_ratio是否设得太低,比如 10) -
rdb_last_bgsave_time_sec > 5且iostat写吞吐(wkB/s)远低于磁盘标称值 → 可能是 fork 开销大(内存碎片高、latest_fork_usec超 1s)、或 RDB 文件太大没开rdb-save-incremental-fsync yes
排除 Redis 自身配置干扰:io-threads 和 no-appendfsync-on-rewrite
很多人调大 io-threads 后发现延迟更高,其实是配置和硬件不匹配。以下参数必须核对:
-
io-threads必须 ≤ 磁盘队列深度 × 2,NVMe 通常设 4~8,机械盘建议保持默认 1 -
io-threads-do-reads必须为no(默认值),开启会破坏复制一致性,官方明确不推荐 -
no-appendfsync-on-rewrite推荐设为yes,否则 AOF 重写期间主线程仍要每秒 fsync,双重压力叠加 -
aof-rewrite-incremental-fsync默认yes,确保重写过程分批 fsync,避免单次落盘过大
真正容易被忽略的点:page cache 和 dirty_ratio 设置
即使磁盘性能足够,Linux 内核也可能主动“卡住” Redis 的写入。关键在于:
-
/proc/sys/vm/dirty_ratio控制 page cache 占内存百分比上限,设太低(如 10)会导致内核频繁触发同步回写,把everysec变成“伪 always” -
/proc/sys/vm/dirty_background_ratio设为dirty_ratio的 50%~70%,让它在缓存快满前就后台刷,避免前台阻塞 - 修改后需确认生效:
sysctl -p或echo 30 > /proc/sys/vm/dirty_ratio - 这个设置影响所有进程,不是 Redis 独有,但对 AOF 场景特别敏感










