负载高而 CPU 空闲
Linux 的平均负载把处于不可中断睡眠(D 状态,TASK_UNINTERRUPTIBLE)的任务也算进去,所以负载高而 CPU 空闲的典型原因是磁盘或网络文件系统阻塞。这类任务不响应信号,无法被直接杀掉,只能等 I/O 返回。定位顺序是:先确认 CPU 确实空闲,再看有多少 D 状态任务以及它们的等待点,然后用 iostat 等指标确认后端是否异常;虚拟机上还要排除宿主占用的 CPU 时间。
基本信息
| 关键命令 | uptime、ps 的 D 状态筛选、iostat -x、cat /proc/loadavg |
|---|---|
| D 状态定义 | TASK_UNINTERRUPTIBLE,等待 I/O 不可被信号打断 |
| 等待点 | ps 的 wchan 列显示内核等待函数 |
| 压力指标 | /proc/pressure/io(内核 4.20 起提供 PSI) |
| 虚拟机补充项 | mpstat 的 steal 列,反映被宿主占用的时间 |
典型使用场景
- 负载告警但 CPU 使用率并不高
- 数据库或文件服务响应明显变慢
- 网络存储(NFS、云盘)抖动引发卡顿
- 虚拟机性能异常需要区分宿主因素
- 排查任务为什么无法被 kill 掉
定位步骤
定位步骤
uptime
cat /proc/loadavg
ps -eo state,pid,wchan:24,comm | awk '$1 ~ /^D/' # 看 D 状态任务与等待点
iostat -x 1 3
cat /proc/pressure/io # PSI 压力指标
vmstat 1 5 | tail -5 # b 列是不可中断睡眠任务数
mpstat -P ALL 1 2 | grep -i steal关键指标读法
| 指标 | 含义 | 判读 |
|---|---|---|
| loadavg 第 4 段 | 运行中任务数与总任务数 | 分子包含 D 状态任务 |
| vmstat 的 b 列 | 不可中断睡眠任务数 | 持续大于零说明存在 I/O 阻塞 |
| ps 的 wchan | 任务等待的内核函数 | 用于区分磁盘、网络文件系统或驱动 |
| iostat 的 await 与 %util | 平均等待时间与设备利用率 | 判断后端设备是否饱和 |
| mpstat 的 steal | 被宿主占用的 CPU 时间 | 虚拟机上的常见干扰源 |
D 状态进程的 wchan 指向内核等待点,要结合应用日志与挂载点判断是本地磁盘还是网络存储问题。
虚拟机上负载高还要看 steal:宿主资源争抢会造成与降频相似的性能表现,只能从宿主侧确认。
常见根因
- 本地磁盘故障或链路降级:iostat 的 await 明显抬高、%util 持续接近饱和
- 网络文件系统抖动:挂载点操作变慢,同时伴随重传或超时日志
- 存储阵列或云盘限流:写入延迟呈周期性升高,与后端配额相关
- 虚拟化环境宿主磁盘繁忙:虚机内表现为无法解释的等待