%wa 高表明IO等待严重,需结合iostat -x 1看await和%util,用pidstat -u -d 1定位高IO进程,dd oflag=direct绕过缓存测真实性能,深层瓶颈可能在文件系统或硬件层。

用 top 看 CPU 和 IO 等待的实时分布
直接运行 top,重点关注右上角的三行负载指标:%Cpu(s) 和 %wa(即 IO wait)。如果 %wa 长期高于 20%,说明内核正在大量等待磁盘或网络 IO 完成,此时 CPU 利用率可能不高,但系统响应慢——这不是 CPU 不够,而是 IO 成了瓶颈。
注意:%wa 是“等待 IO 的 CPU 时间占比”,不是“IO 设备忙的比例”。它反映的是有进程在就绪队列里干等 IO 返回,而不是 CPU 空转。所以即使 %Cpu(s) 显示 30% idle,只要 %wa 高,就别急着加 CPU。
-
top默认不显示线程模式,按H可切换,排查单个高 IO 进程时有用 - 某些虚拟化环境(如 KVM)中
%wa可能被虚报,需结合iostat -x 1交叉验证 -
top的采样间隔默认是 3 秒,对瞬态 IO 尖峰不敏感,可按s键临时调到 0.5 秒
用 iostat -x 1 定位具体设备和延迟
iostat -x 1 每秒输出一次扩展统计,关键看三列:%util、await、svctm(已弃用,忽略)。
%util 接近 100% 表示设备几乎一直在处理请求,但要注意:SSD 的并行能力远高于 HDD,%util 高不一定等于瓶颈;而 await(平均每次 IO 的等待+服务时间)超过 10ms(HDD)或 1ms(SSD)才真正可疑。
- 若
await高但%util很低,可能是应用发了太多小随机 IO,或存在锁竞争(如 ext4 journal 争抢) -
r/s和w/s突增但rkB/s/wkB/s不高,大概率是小 IO 导致的上下文切换/中断开销问题 - NVMe 设备会显示多个队列(如
nvme0n1p1),别只盯着nvme0n1看总值
区分 CPU 密集型 vs IO 密集型进程:用 pidstat -u -d 1
pidstat -u -d 1 同时输出每个进程的 CPU 使用率(%CPU)和 IO 读写速率(kB_rd/s、kB_wr/s),比单独看 top 或 iotop 更直观判断“谁在拖慢系统”。
经过对v6.0为期一个月的调整,WRMPS v6.1 正式和大家见面,此版本在原6.0的基础上除修正旧版本所有问题外,还增加了很多人性化的功 能。 特别是在推广易功能上,做了很大提升,其包含的品牌店铺、竞价广告等服务内容将极大的提高站长的收益,而且快捷方便的服务购买支付 流程,将非常有效的推动客户在您的网站上进行消费。
典型误判场景:一个 Java 进程 %CPU 占 80%,但同时 kB_wr/s 达 50MB/s —— 它可能一边做计算一边刷日志,单纯降 CPU 优先级没用,得查日志落盘策略。
- 加
-t参数可显示线程级数据,适合排查 GC 日志刷盘或 Netty flush 线程阻塞 - 注意单位:默认是 kB,不是 KB;遇到大数值时可用
-h开启人类可读格式 - 如果某进程
%CPU低但Command列显示D(uninterruptible sleep),基本可断定它卡在 IO 路径里(如 NFS hang、坏盘重试)
绕过缓存测真实 IO 性能:用 dd with oflag=direct
很多“IO 慢”其实是 page cache 在捣鬼。用 dd if=/dev/zero of=testfile bs=1M count=1024 oflag=direct 绕过缓存直写磁盘,才能测出设备真实吞吐。对比 oflag=sync(同步写)和 oflag=direct 的耗时差异,还能判断存储栈是否支持高效异步 IO。
-
oflag=direct要求bs是文件系统逻辑块大小的整数倍(通常是 4K),否则会 fallback 到缓存模式且不报错 - 测试前用
echo 3 > /proc/sys/vm/drop_caches清缓存,避免上次测试污染结果 - SSD 测试要预填充(preconditioning),空盘和满盘性能可能差 5 倍以上;生产环境更应关注
fio --name=randwrite --ioengine=libaio --direct=1这类混合负载模拟
真正难的不是分清 CPU 还是 IO,而是当 %wa 高、iostat 却看不出设备瓶颈时——那往往卡在文件系统层(如 XFS allocation group 锁)、块设备驱动(如 multipath 路径切换)、甚至硬件固件(NVMe controller thermal throttle)。这时候得看 /proc/diskstats 的 ios_pgr 字段,或者用 perf record -e block:block_rq_issue,block:block_rq_complete 抓 IO 生命周期事件。










