iostat + iotop 搞定磁盘 IO 故障

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/sw/s 每秒读写请求数(IOPS) 反映 IO 频率
rkB/swkB/s 每秒读写数据量 反映吞吐量
rrqm/swrqm/s 每秒合并的读写请求数 合并越多,说明 IO 调度在优化
r_awaitw_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:根据进程类型处理

进程类型 常见例子 处理方向
数据库 mysqldpostgres 查慢查询、优化索引、调整缓存
日志服务 rsyslogdjournaldfilebeat 调整日志级别、优化轮转策略
应用进程 Java/Python/Go 服务 检查批处理、限流、回滚变更
系统进程 kworkerjbd2 可能是文件系统日志或内核刷盘
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

七、总结

  1. 先全局后局部vmstat/topiostatiotop/pidstat
  2. 核心指标%util 看饱和,await 看延迟,aqu-sz 看排队
  3. 定位到进程后:结合 lsofstrace、业务日志判断根因
  4. 不要只看一个指标%util 高不一定慢,await 高才说明体验受影响
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇