在印度机房用 iostat 看盘,%util 骗了我一下午
孟买机房一台 8 核 32G 的采集机,Ubuntu 20.04,系统盘和一块 2T 的数据盘都是云上挂的云盘(不是本地 NVMe,这点很关键)。现象:采集进程写盘时断时续,写入延迟从平时 2ms 跳到 300ms 以上,但 top 里 wa 只有 5% 上下,iostat -x 1 里数据盘 %util 长期 60~70%,看着“没打满”。我先按老习惯怀疑是应用层批量写太大,调了 buffer 大小,没用。
后来把观测粒度改细,问题才露出来:
iostat -x 1 /dev/vdb
iostat -d -m 1 /dev/vdb
cat /proc/diskstats
iostat -x 的 %util 是按“设备有未完成 IO 的时间占比”算的,对能并发处理多请求的设备(云盘后端、RAID、NVMe)来说,它到 100% 也不代表饱和,反过来它没到 100% 也不代表还有余量。真正对齐现象的是 await 和队列深度:那台机器上 aqu-sz 经常到 8~12,r_await/w_await 跟着涨,%util 却还是六七十。也就是说瓶颈在排队,不在“设备忙”。
我的做法是把判断依据换掉:
# 看饱和度,不只看 util
iostat -x 1 5 | awk 'NR>3 {print $1, $NF, $(NF-4), $(NF-3)}'
# 单次采样里直接看队列和延迟
sar -d -p 1 10
配合把采集进程的写入从“每来一条就 write”改成 128KB 一批、O_DIRECT 关掉(云盘上开 O_DIRECT 反而因为对齐问题多出小 IO),延迟才稳定下来。代价是进程被 kill 时最多丢最后一批,所以又加了一个每 5 秒的 fsync,这个取舍要看业务能不能接受。
会失效的地方:本地 SATA SSD 上 %util 的参考意义比云盘大得多;如果盘本身是单队列的机械盘,队列深度上不去,%util 反而更可信。我还在小规格云盘上遇到过 await 被后端限流放大、但 aqu-sz 不高的情形,那种只能看应用侧 P99。另外 iostat 版本不同字段位置会变,上面 awk 的列号别直接抄到别的机器。
你们在云盘上判断 IO 瓶颈,是看 await、aqu-sz 还是直接压测打点?我想知道有没有更稳的单一指标。
0 条评论
还没有评论,写下第一条。