iostat + iotop 搞定磁盘 IO 故障
核心思路:先用 iostat 定位“哪块盘”有瓶颈,再用 iotop 定位“哪个进程”在搞事。
一、iostat:设备级 IO 监控
1.1 安装
# CentOS / RHEL
yum install -y sysstat
# Ubuntu / Debian
apt-get install -y sysstat
1.2 常用命令
# 最常用:每秒刷新,看扩展指标
iostat -x 1
# 只看磁盘、跳过空闲设备(推荐生产环境使用)
iostat -dxz 1
# 以 MB 为单位显示,刷新 3 次
iostat -x -m 1 3
# 只看某块盘
iostat -x /dev/sda 1
# 同时显示 CPU 和磁盘(适合先看 wa)
iostat -xc 1
1.3 输出字段解读
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 1.00 0.00 8.00 0.00 0.00 0.00 0.00 0.00 0.80 0.00 0.00 8.00 0.80 0.08
| 字段 | 含义 | 判断标准 |
|---|---|---|
r/s、w/s |
每秒读写请求数(IOPS) | 反映 IO 频率 |
rkB/s、wkB/s |
每秒读写数据量 | 反映吞吐量 |
rrqm/s、wrqm/s |
每秒合并的读写请求数 | 合并越多,说明 IO 调度在优化 |
r_await、w_await |
读/写平均等待时间(ms) | > 10ms 需关注,> 100ms 严重 |
aqu-sz(avgqu-sz) |
平均 IO 队列长度 | 队列长说明请求堆积 |
svctm |
平均每次 IO 服务时间 | 已废弃,参考价值有限 |
%util |
设备利用率 | 持续 > 80% 繁忙,接近 100% 基本确认 IO 瓶颈 |
1.4 关键判断逻辑
await >> svctm → IO 队列过长,磁盘响应差
await ≈ svctm → 几乎没有等待,磁盘性能较好
%util > 80% → 磁盘设备饱和
%util ≈ 100% → 磁盘基本被占满,需要进一步定位进程
注意:
iostat第一次输出是开机至今平均值,从第二次开始才是实时采样值。
二、iotop:进程级 IO 监控
2.1 安装
# CentOS / RHEL
yum install -y iotop
# Ubuntu / Debian
apt-get install -y iotop
2.2 常用命令
# 交互式查看(需要 root)
sudo iotop
# 只显示有实际 IO 的进程
sudo iotop --only
# 只显示进程,不显示线程,过滤无 IO 的
sudo iotop -oP
# 非交互模式,批量输出 5 次
sudo iotop -boP -n 5
# 指定刷新间隔 2 秒
sudo iotop -d 2
2.3 输出字段解读
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
123 be/4 root 0.00 B/s 12.34 M/s 0.00 % 98.32 % mysqld
| 字段 | 含义 |
|---|---|
TID |
线程 ID |
PRIO |
IO 优先级 |
DISK READ / DISK WRITE |
磁盘读/写速率 |
SWAPIN |
swap 换入比例,高说明内存不足 |
IO> |
该进程占用 IO 的时间百分比 |
COMMAND |
进程/命令名 |
2.4 注意事项
iotop需要 root 权限,且依赖/proc中的 IO 统计。- 某些内核版本或容器中可能无法使用,可改用
pidstat -d 1替代。
三、标准排查流程
步骤 1:确认系统是否有 IO 问题
# 看 CPU 的 wa(IO 等待)是否高
top
vmstat 1 5
如果 wa% 持续较高(如 > 20%),说明 CPU 大量时间花在等 IO。
步骤 2:用 iostat 定位磁盘
iostat -dxz 1
关注:
– 哪块 %util 高
– await 是否异常
– aqu-sz 是否堆积
步骤 3:用 iotop 定位进程
sudo iotop -oP
找到高 IO 的进程后:
– lsof -p <PID>:看进程在读写哪些文件
– ls -l /proc/<PID>/fd:看打开的文件描述符
– strace -p <PID>:跟踪系统调用
步骤 4:根据进程类型处理
| 进程类型 | 常见例子 | 处理方向 |
|---|---|---|
| 数据库 | mysqld、postgres |
查慢查询、优化索引、调整缓存 |
| 日志服务 | rsyslogd、journald、filebeat |
调整日志级别、优化轮转策略 |
| 应用进程 | Java/Python/Go 服务 | 检查批处理、限流、回滚变更 |
| 系统进程 | kworker、jbd2 |
可能是文件系统日志或内核刷盘 |
| swap 相关 | kswapd0 + si/so 高 |
内存不足,考虑释放或扩容 |
四、实战案例
案例 1:服务器卡顿,CPU 和内存都不高
# 1. 看 CPU 等待
vmstat 1 5
# 输出中 wa 持续 30%+
# 2. 定位磁盘
iostat -dxz 1
# sdb 的 %util 接近 100%,await 200ms+
# 3. 定位进程
sudo iotop -oP
# 发现 mysql 占 90%+ 的 IO
# 4. 深入分析
mysql -e "SHOW PROCESSLIST;"
# 发现有慢查询全表扫描
结论:慢查询导致磁盘 IO 打满,优化 SQL 后恢复。
案例 2:磁盘 IO 高但 iotop 看不到明显进程
可能原因:
– 是内核级 IO(如文件系统日志 jbd2、RAID 同步、快照合并)
– 容器环境中进程在别的 namespace
– 进程生命周期短,iotop 没抓到
排查:
# 看内核消息
dmesg | grep -iE "error|fail|ata|sd|IO|bad"
# 看块设备事件
blktrace -d /dev/sda
# 用 pidstat 做历史统计
pidstat -d 1 10
案例 3:%util 不高但 await 很高
可能原因:
– 磁盘本身响应慢(老机械盘、RAID 卡电池故障、存储网络抖动)
– IO 请求块大小不均,队列调度不均
排查:
# 看 SMART 信息
smartctl -a /dev/sda
# 看挂载参数
mount | grep /dev/sda
五、扩展工具
| 工具 | 用途 |
|---|---|
vmstat |
看 CPU wa、内存 swap、整体负载 |
pidstat -d 1 |
进程级 IO 历史统计,iotop 替代品 |
sar -d |
历史 IO 数据分析 |
dstat -d |
综合资源监控 |
blktrace / btrace |
块设备 IO 事件追踪 |
smartctl |
磁盘健康检测 |
lsof |
查看进程打开的文件 |
strace |
跟踪进程系统调用 |
六、常用命令速查
# 综合判断系统 IO 压力
vmstat 1 5
# 定位繁忙磁盘
iostat -dxz 1
# 定位高 IO 进程
sudo iotop -oP
# iotop 不可用时的替代
pidstat -d 1
# 看进程在读写什么
lsof -p <PID>
# 跟踪系统调用
strace -p <PID>
# 磁盘健康
smartctl -a /dev/sda
七、总结
- 先全局后局部:
vmstat/top→iostat→iotop/pidstat - 核心指标:
%util看饱和,await看延迟,aqu-sz看排队 - 定位到进程后:结合
lsof、strace、业务日志判断根因 - 不要只看一个指标:
%util高不一定慢,await高才说明体验受影响