深色模式
IO 瓶颈排查
摘要:
%util到 100% 并不总代表磁盘饱和。本文用await、avgqu-sz、aqu-sz等指标判断真实排队情况,再用 iotop、pidstat 定位到进程,最后列出最常见的几种误判。
适用环境
bash
which iostat iotop pidstat sar # 来自 sysstat / iotop 包
lsblk
cat /sys/block/sda/queue/scheduler 2>/dev/null1
2
3
2
3
排障步骤
第 1 步:确认整机存在 IO 压力
bash
vmstat 1 5 # 关注 wa 列、b 列(不可中断睡眠进程数)
iostat -x 1 31
2
2
第 2 步:读懂 iostat -x 的关键列
bash
iostat -x -d 1 3 /dev/sda1
r/s、w/s:每秒 IOPSrkB/s、wkB/s:吞吐量await:请求从发出到完成的平均毫秒数,最关键avgqu-sz/aqu-sz:平均队列长度,持续大于 1 说明在排队%util:设备处于忙状态的时间占比
第 3 步:判断是否真的饱和
bash
sar -d -p 1 5
cat /proc/loadavg
ps -eo stat,pid,comm | awk '$1 ~ /D/'1
2
3
2
3
真正的饱和表现为:await 明显高于设备正常值、aqu-sz 持续排队、存在大量 D 状态进程。
%util 100% 不等于饱和
%util 只统计"有请求在处理"的时间比例,RAID 组或多队列 SSD 可以在 %util 100% 时仍有余量。应以 await 和排队长度为准。
第 4 步:定位到进程
bash
iotop -o -P -d 1 -n 5
pidstat -d 1 51
2
2
第 5 步:看单个进程的 IO 画像
bash
cat /proc/<PID>/io
strace -p <PID> -e trace=read,write,fsync -c1
2
2
read_bytes/write_bytes 与 rchar/wchar 差异大,说明大量读被页缓存吸收或写入被缓冲。
对生产进程长时间 strace
strace -p 会显著拖慢目标进程(每次系统调用都穿越 ptrace)。建议加 -c 与明确的超时,控制在数秒内。
第 6 步:区分随机小 IO 与顺序大 IO
bash
iostat -x -d 1 3 | awk 'NR>3 && $2>0 {print "IOPS="$2+$3" await="$NF-2}'1
同样 100MB/s 吞吐,4K 随机写与 1M 顺序写的设备压力相差几十倍。优化方向完全不同:随机写靠合并与缓存,顺序写靠限流与错峰。
验证
bash
iostat -x -d 1 3
vmstat 1 5
ps -eo stat,pid,comm | awk '$1 ~ /D/' | head1
2
3
2
3
常见坑
iowait 高但磁盘没问题
iowait 只是 CPU 空闲时恰好有 IO 等待,CPU 繁忙时 iowait 反而偏低。它不能作为唯一判据。
网络存储(NFS/云盘)指标失真
云盘与 NFS 的 %util 常无意义,应看 await 与云厂商提供的卷队列深度指标。
fsync 频繁导致的隐性瓶颈
写入量不大但每次都 fsync,吞吐被事务提交次数卡死,表现为 IOPS 低但延迟高。
为降 IO 直接关闭数据落盘或同步
关闭 fsync、改成异步刷盘会在掉电时丢数据。任何持久化降级都要先评估数据丢失容忍度。