
真正瓶颈需综合await、aqu-sz和I/O模式判断:sda的%util=100%但r/s=0,w_await=12.43ms>10ms且aqu-sz=1.54>1,wareq-sz=10.45KB偏小,表明随机小写导致IOPS瓶颈,非带宽不足。
iostat 输出里真正的瓶颈项直接看 %u 容易误判——它只反映设备忙闲比例,不等于 I/O 瓶颈。真正要盯的是
tilawait(平均每次 I/O 等待毫秒数)和 r_await/w_await。如果 await > 10ms(机械盘)或 > 1ms(SSD),且 %util 持续接近 100%,才说明 I/O 队列积压严重。
iostat -x 1 是必须加的参数,-x 才能显示扩展指标avgqu-sz:长期 > 1 表示队列中常有未处理请求,结合高 await 就是典型瓶颈信号iostat -x 1 连续观察,避免单次快照误导;瞬时尖峰可能来自临时写入,持续 5 秒以上高值才需干预pidstat -d 定位吃 I/O 的具体进程iotop 直观但依赖内核模块,有些生产环境禁用;pidstat -d 更轻量、兼容性更好,且能输出每秒读写字节数和 I/O 请求次数。
pidstat -d 1,重点关注 kB_rd/s 和 kB_wr/s 列,数值突增的进程就是嫌疑对象MB_wr/s 持续 > 50 且磁盘 await 同步升高,基本可锁定为源头dd if=/dev/zero of=test bs=1M count=1024 oflag=direct 加 oflag=direct 可绕过 page cache,测出真实磁盘吞吐,避免被缓存掩盖问题blktrace 抓取底层 I/O 路径,确认是不是内核或驱动层卡住当 iostat 显示高 await、pidstat 却没发现明显大户时,问题可能在块层——比如多路径切换异常、NVMe 驱动 bug、或 LVM thin pool 元数据锁争用。
blktrace -d /dev/sda -o - | blkparse -i - 实时解析(需 root 权限)Q(queue)、G(get request)、M(merge)、I(issue)之间的时间差;若 Q→G 延迟大,说明 I/O 在队列里等太久;若 I→C(complete)超长,可能是硬件响应慢或驱动挂起cat /proc/diskstats 查 io_ticks(设备忙时间,单位 ms):如果该值增长远快于 wall clock,说明设备真正在满负荷运转常见陷阱:ext4 默认启用 barrier=1,XFS 在某些内核版本下 journal 写入阻塞主线程,或者挂载时漏掉 noatime 导致大量元数据更新。
mount | grep " / ",确认根分区是否含 noatime、commit=60(降低 sync 频率)等优化项logbsize=256k 和 logbufs=8;ext4 建议用 data=writeback(仅适用于能接受日志丢失风险的场景)sync 类调用:用 strace -p $PID -e trace=fsync,fdatasync,msync 检查应用是否频繁强制刷盘sudo iostat -x 1 Linux 5.15.0-101-generic (host) 04/12/2025 _x86_64_ (8 CPU)Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util sda 0.00 124.00 0.00 1296.00 0.00 12.00 0.00 8.77 0.00 12.43 1.54 0.00 10.45 8.04 100.00
上面这个例子中,sda 的 %util 是 100%,但 r/s 为 0,说明全是写;w_await=12.43ms + aqu-sz=1.54 表明写请求在队列中等待明显,再结合 wareq-sz=10.45KB(写大小偏小),大概率是随机小写导致 IOPS 吃紧,而非带宽跑满。
真正难排查的,往往是多个小进程分散写同一块日志区域,pidstat 看不出峰值,但 blktrace 会暴露大量 Q→I 微秒级延迟跳变——这种毛刺型瓶颈,得靠持续采样+时间对齐才能抓到。