真正瓶颈需综合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 输出里真正的瓶颈项
直接看 %util 容易误判——它只反映设备忙闲比例,不等于 I/O 瓶颈。真正要盯的是 await(平均每次 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,说明设备真正在满负荷运转
检查文件系统和挂载选项是否拖慢 I/O
常见陷阱:ext4 默认启用 barrier=1,XFS 在某些内核版本下 journal 写入阻塞主线程,或者挂载时漏掉 noatime 导致大量元数据更新。
- 运行
mount | grep " / ",确认根分区是否含noatime、commit=60(降低 sync 频率)等优化项 - 对数据库类负载,XFS 推荐加
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/2024 _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 微秒级延迟跳变——这种毛刺型瓶颈,得靠持续采样+时间对齐才能抓到。










