iostat -dx 1 是最稳的设备级实时监控起点,直接从内核驱动层抓数据,可清晰查看每秒读写量(r/s、w/s、rkb/s、wkb/s)和延迟(await、r_await、w_await),%util >80%需结合avgqu-sz>1和r_await/w_await>20ms综合判断瓶颈。

iostat -dx 1 看设备级实时吞吐和延迟
想一眼看清整块盘当前每秒读写多少、卡不卡,iostat -dx 1 是最稳的起点。它不依赖进程视角,直接从内核驱动层抓数据,适合快速判断是不是磁盘本身扛不住了。
-
%util持续 >80% 是危险信号,但别单看它——NVMe 盘多队列下这个值早早就顶了,得配合avgqu-sz(平均队列长度)一起看:>1 就说明请求在排队 -
r_await或w_await超过 20ms 必须警惕,这比 %util 更早暴露延迟瓶颈;SSD 正常应稳定在 1–3ms,机械盘长期 >15ms 就有问题 - 加
-d参数(iostat -dx 1中已隐含)才能屏蔽 CPU 行干扰;测单盘时用iostat -xk 1 /dev/nvme0n1,避免被其他设备噪音带偏 - 注意设备名必须准确:
lsblk确认是nvme0n1还是sda,混用会导致数据完全对不上
iotop -o 找出正在疯狂读写的进程
iotop -o 是定位“谁在作妖”的最快方式,但它默认只显示此刻有 IO 活动的进程,静默状态的不会出现——不是没 IO,是刚好空闲了。
- 必须用
sudo iotop -o,非 root 权限下读不到/proc/*/io,会静默跳过所有用户进程 -
IO%列比DISK READ/WRITE更关键:它反映该进程占设备总带宽的比例;如果java或mysqld长期 >70%,基本就是业务负载源 - 快捷键
O(Shift+O)按 IO 带宽降序,p切换 PID/TID 显示,避免被线程 ID 搞混 - 容器环境要注意:
iotop显示的是宿主机 PID,不是容器内 PID,需用docker top或crictl ps对齐
pidstat -d 1 盯住指定服务的实时读写速率
要精确监控 nginx、Java 或 Python 服务的 IO 速率,pidstat -d 1 是唯一能输出 rkB/s 和 wkB/s 的命令,这两个字段才是你要盯的“每秒读写 KB 数”。
- 必须带采样间隔:
pidstat -d 1,只输pidstat -d会执行完立刻退出;千万别用pidstat -d 0,会让内核疯狂采样,终端卡死甚至触发 OOM - 用
pgrep -f定位 PID 最可靠:pidstat -d 2 -p "$(pgrep -f 'java.*-Dspring')",比ps aux | grep抗干扰强得多 -
rkB/s和wkB/s是瞬时速率,不是累计量;若某进程wkB/s长期稳定在 20000+,说明它正持续写入约 20MB/s,已接近 SATA SSD 吞吐瓶颈 - 输出里
%MEM、RSS等内存字段和 IO 完全无关,只是共用一行显示,别被位置误导
dd if=/dev/zero of=... oflag=direct 测真实写速,别被缓存骗了
用 dd 测速最容易踩坑:漏掉 oflag=direct,报出来的就是内存拷贝速度,不是磁盘真实吞吐。
- 关键参数只有四个:
if=/dev/zero(无 IO 开销)、of=/mnt/testfile(路径必须落在目标盘上,别写/tmp)、bs=1M(块大小设大些,太小会放大调度开销)、oflag=direct(强制直写磁盘) - 别用
conv=notrunc或seek追加写,那会引入 seek 时间,不再是纯顺序写 - 测试前建议清缓存:
sync && echo 3 > /proc/sys/vm/drop_caches,否则第二次结果会异常快 - 重复测 2–3 次取稳定值,单次结果受预热、元数据开销影响太大
await 高但 svctm(已废弃)或估算的服务时间低,说明卡在队列里——可能是上层锁竞争或调度问题;只有 svctm 高才真代表磁盘响应慢。这个差值经常被忽略。











