首页/系统/Linux 运维命令速查/场景:磁盘 IO 慢怎么定位
性能与监控48 条

场景:磁盘 IO 慢怎么定位

应用变慢怀疑磁盘:从设备利用率到进程归因,再到文件级热点,四级下钻。

Linux 运维命令速查系统更新于 2026-10-13

这个场景要解决什么

应用变慢、怀疑磁盘时,按层下钻比乱猜有效:先看设备层的利用率与延迟,再看哪个进程在读写,最后定位到具体文件与系统调用。每一层回答一个不同的问题——设备层回答哪块盘堵了,进程层回答谁在堵,文件层回答读写的是什么。层别对了,优化方向才有意义。

基本信息

适用场景磁盘延迟高、吞吐下降、应用响应变慢
目标定位到设备、进程与文件三级瓶颈
工具链iostat、iotop、pidstat、strace、lsof
注意数据库自带缓存时块层指标可能平淡,别死磕磁盘

第 1 步 设备层

第 1 步 设备层
iostat -xz 1 5        # -x 扩展指标,-z 隐藏空闲设备
# 重点看 %util、await、r/s、w/s 与队列长度

第 2 步 进程层

第 2 步 进程层
iotop -oPa -b -n 2 | head -n 25
pidstat -d 1 3 | tail -n +3 | sort -k5 -rn | head
# 找出读写量最大的进程,再结合 ps 看它是什么服务

第 3 步 文件与调用栈

第 3 步 文件与调用栈
lsof -p 1234 | grep -E 'REG|DIR' | head
strace -f -e trace=read,write,fsync -p 1234 -T 2>/dev/null | head -n 40
# -T 会显示每次调用的耗时,能直接看到哪一步慢

第 4 步 排除缓存在捣乱

第 4 步 排除缓存在捣乱
grep -E 'Cached|Dirty|Writeback' /proc/meminfo
vmstat 1 3            # bi/bo 才是真实的块层活动
# 写入量集中在 Writeback,说明还在刷页缓存

iostat 关键列

列含义怎么判
%util设备忙碌时间占比接近 100% 说明设备接近饱和
await每个 IO 的平均等待加服务时间机械盘上到两位数毫秒就要警觉
r/s、w/s每秒读、写次数要和队列深度一起看
rkB/s、wkB/s每秒读写字节数用来区分延迟问题与吞吐问题
aqu-sz平均请求队列长度持续升高说明设备来不及处理
%iowaitCPU 等待 IO 的时间占比仅为 CPU 侧统计,不代表整机 IO 压力
顺序建议是先看 %util 与 await 确认设备确实吃紧,再用 iotop 或 pidstat 找到进程,最后用 strace 看具体调用;跳过中间的进程归因,容易把缓存行为误当成磁盘故障。
小 IO 高频场景下 %util 达到 100% 未必说明设备到极限,先看 await 是否恶化;反过来 await 很漂亮而业务仍慢,问题多半不在磁盘。

从指标到结论

  • 利用率高、await 高、队列长:设备确实到瓶颈,考虑加缓存或换更高性能的介质
  • 利用率高、await 正常:多为小 IO 高频,可在应用侧考虑合并写
  • 利用率不高、await 高:检查是否存在单笔大 IO,或存储链路上的问题
  • 各项指标都低但业务慢:瓶颈不在磁盘,回到 CPU、内存或下游依赖上找

确认读写模式

确认读写模式
iostat -x 1 3 | grep -E 'Device|sda|sdb'   # 看 r/s 与 w/s 的比例
iotop -oPa -b -n 1 | head -n 15            # 看是读多还是写多
cat /sys/block/sda/queue/scheduler         # 查看当前 IO 调度器
随机小 IO 密集的数据库盘值得调调度器与队列深度;以顺序读写为主的日志盘更依赖介质本身,调参数收益有限。
调优前先留一份基线:把当前的 iostat 与 iotop 输出存档,改动后再对比,否则很难判断改动是变好还是变坏。
容器与虚拟机的 IO 会先经过宿主机的存储栈,容器内看到的常是虚拟设备;要落到真实盘上,还得回到宿主机层面看。
有些看起来像 IO 故障的现象其实是磁盘写满:写入失败与重试同样会推高 await。动手查 IO 之前先 df -h 与 df -i 各看一眼,排除空间与 inode 耗尽的干扰。
定位到具体文件后先判断它是数据文件、日志还是索引:日志类可以调级别或改成异步写,数据文件更适合从索引设计和批量提交入手。

从现象到方向

现象倾向原因下一步
等待高但设备利用率低请求小且数量多看平均请求大小与发起进程
利用率高且队列深设备层已到瓶颈看读写模式与并发度
应用慢而块层平淡被缓存或锁吸收转查数据库与业务逻辑
周期性尖峰定时任务叠加把任务时刻与曲线对齐
持续高写入落盘与归档策略检查刷盘与日志配置
定位顺序是先看设备层是否饱和,再看是哪个进程发出的请求,最后确认读写模式以及是否被缓存掩盖。生产环境上做深入跟踪要限时并缩小范围,观测手段本身的开销有时足以把问题放大一级,务必在低峰或单实例上先验证方法。

易错点

  • 只盯 %util 就下结论,忽略 await 与队列深度,容易把正常的顺序写当成瓶颈
  • 用 %iowait 代表整机 IO 压力:它只是 CPU 侧统计,多核机器上会被摊薄
  • 数据库的读被自身缓冲池吸收,块层指标平淡而业务慢,此时该查锁与慢查询而不是磁盘
  • 在容器里跑 iotop 只能看到本容器的进程,宿主机侧要换 nsenter 或在宿主执行
  • strace 附加到高吞吐进程会显著拖慢它,生产上要限时并缩小调用过滤范围
  • 把单次指标快照当成结论:存储问题常与缓存、刷盘周期和业务批次相关,短时采样很容易落在缓存命中区间内,结论会与真实现状相反

数据来源与参考

  • man 1 iostat
  • man 1 pidstat
  • man 8 iotop

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌