负载 20 但 CPU 只有 10%:把 IO 等待和 D 状态进程揪出来
监控里 load average 冲到 20,CPU 使用率却只有 10%,第一反应往往是「是不是被挖矿了」。实际上更常见的是磁盘 IO 打满,进程卡在不可中断睡眠(D 状态)。
load average 统计的是「运行中 + 不可中断」的进程数,所以一个卡在磁盘 IO 的进程也算一份负载。
先说结论
先看 iowait 和 D 状态进程,再看是谁在打磁盘。 top 里按 1 看每核,按 shift+P/M 排序只能看 CPU/内存,D 状态要用 ps 单独筛。
- top 看 %wa(iowait)是否偏高
- ps -eo state,pid,comm | awk '$1=="D"' 找 D 状态进程
- iostat -x 1 看 %util 和 await
- iotop -oPa 看具体进程的写放大
先把问题说清楚
CPU 使用率只统计真正在跑的指令;进程等待磁盘时不计入 CPU,但会推高 load。
云主机的「突发性能实例」还有 CPU 积分耗尽的问题:表面 CPU 不高,实际被限流,表现为所有操作都变慢。
具体怎么做
按顺序执行,每步都验证完再进下一步:
- top 里按 1 展开每核,观察 %wa 与 %si(软中断)
- ps -eo state,pid,ppid,comm | awk '$1 ~ /D/' 找卡住的进程
- iostat -x 1 5 看设备 %util 与 await,超过 80% 基本就是瓶颈
- iotop -oPa 定位写放大源头(数据库、日志、备份)
- 如果是云盘,对照云监控的 IOPS/吞吐上限,别只盯系统内指标
参数与成本对照
把关键数值摊开,方便判断该选哪条路:
| 指标 | 含义 | 异常阈值 |
|---|---|---|
| load average | 运行 + 不可中断进程数 | 持续 > 核数 × 2 |
| %wa | CPU 等待 IO 的时间占比 | > 20% 需关注 |
| %util | 设备繁忙度 | > 80% 视为瓶颈 |
| await | 单次 IO 平均耗时(ms) | 机械盘 > 50,SSD > 10 |

几个容易踩的坑
下面这些是最常见的错误做法:
- 只看 load 就扩容:结果 IO 瓶颈没解决,钱白花
- 把 D 状态进程 kill -9:内核态无法被杀,会一直挂着
- 忽略软中断:网卡单队列打满也会表现为「负载高」
- 在容器里看 load:看到的是宿主机的值,容易误判
最后补两句
排查顺序固定为:load → CPU/IO 拆分 → 进程级定位 → 设备级确认。跳步就会把 IO 问题当成 CPU 问题。
工具是手段,理解机制才是能力。命令记不住没关系,知道「该看什么」就够了。
评论 (3)
照着做了一遍,确实少走弯路。第二步最容易漏,建议顺手加个检查清单。
比「一键脚本」有用多了,知道为什么比知道怎么做重要。
补充一句:不同版本行为会变,动手前先确认自己的版本号。
发表评论