iowait高但iostat无异常说明I/O等待源于非磁盘环节,需排查容器文件系统、block层延迟、tmpfs/overlayfs等伪设备及内核路径阻塞。
当
sar
显示 %iowait 持续很高(比如 >30%),但
iostat -x 1
却看不出某块磁盘的 %util、await 或 avgqu-sz 明显异常——这说明 I/O 等待不是来自“典型慢盘”,而是被系统其他环节“吃掉”了,或者 I/O 行为本身很隐蔽。这种情况常见于容器环境、文件系统层开销大、短时突发 IO、或内核路径阻塞等场景。
先确认 iowait 是否真由磁盘 I/O 引起
iowait 高 ≠ 磁盘忙。它只是 CPU 在空闲时等待 I/O 完成的时间占比。所以要排除干扰:
检查 CPU 是否真的有 idle 时间:如果 %idle 极低(如
用
vmstat 1
看 b(blocked 进程数)和 r(runnable 进程数):若 b 长期 >0,说明确有进程卡在不可中断睡眠(D 状态),这才是真 I/O 阻塞信号;
运行
pidstat -u 1
和
pidstat -d 1
对照看:如果 %iowait 高,但各进程的 IO KB/s 和 %io 都很低,大概率是 block 层或驱动层延迟,而非应用写得多。
盯住 block 层和 bio 路径,而不是只看设备层
iostat 只统计到 request queue 层面,对更上游的 bio 分发、合并、调度不敏感。以下命令能挖得更深:
Docker Desktop(windows)
当前 Docker 最新稳定版本之一,主要针对稳定性和兼容性进行了修复优化,适合生产环境与日常开发使用。该版本继续强化 AI 开发支持、容器日志管理以及 Docker Engine 的安全能力,对 Windows/macOS/Linux 平台兼容性进行了进一步优化。
下载
cat /proc/diskstats
:对比各设备的 “# of IOs merged”、“# of requests”、“# of sectors read/written”,看是否大量 IO 被 merge 掉,导致 iostat 的 r/s/w/s 失真;
blktrace -d /dev/sda -o - | blkparse -i -
(需 root):捕获真实下发的 bio 和 request 事件。重点关注 “Q”(queue)、“G”(getrequest)、“C”(complete)之间的时间差。若 Q→G 延迟长,说明 block 层调度/队列深度不足;若 G→C 很长,才指向设备或驱动问题;
echo 1 > /sys/block/sda/stat
(谨慎)+ 再读一次 /sys/block/sda/stat:可临时触发一次 stat 刷新,辅助判断是否因统计缓存导致 iostat 滞后。
排查 overlayfs、tmpfs、loop 设备等“非物理盘”路径
尤其在 K8s 或 Docker 环境中,高 iowait 常来自文件系统层,而非底层磁盘:
运行
findmnt -t overlay,overlayfs,xfs,ext4,tmpfs
,确认是否有 overlayfs 下层(lowerdir/uppperdir)挂载在高 IO 目录;
查容器数据目录是否用了
emptyDir
或
hostPath
绑定到 tmpfs(内存盘):tmpfs 写满会触发 swap 或 OOM Killer,但 iostat 不显示任何磁盘活动;
用
lsof + grep -E "(REG|DEL)"
查高 IO 进程打开的文件路径,重点识别:
、
、
——这些都不是真实磁盘,但会消耗 CPU 在 copy-up、page cache 回写等操作上。
检查内核日志与 multipath/NVMe 特定行为
某些硬件/驱动问题不会让磁盘“忙”,却会让 IO 在途中卡住:
dmesg -T | grep -i "block\|nvme\|multipath\|fail\|timeout"
:查找 “blk_update_request: I/O error”、“nvme 0000:01:00.0: timeout”, 或 multipath “
switch
ing to [path]” 类日志;
NVMe 设备注意
cat /sys/class/nvme/nvme0/nvme0n1/queue_depth
和当前
cat /sys/class/nvme/nvme0/nvme0n1/io_poll_delay
:队列过浅或轮询延迟设置不当,会导致大量 short-lived IO 在 kernel 中排队,但 iostat 看不出压力;
用
perf record -e block:block_rq_issue,block:block_rq_complete -a sleep 10
+
perf script
:看 issue → complete 的延迟分布,若大量请求耗时 >10ms 且未落到设备,就说明 block 层或 driver 是瓶颈。
/var/lib/kubelet/pods/.../volume-subpaths/.../dev/loop*/tmp/xxx