朕喜技术(ZhenxiJS)
2026.08.31
1 分钟阅读
Linux 高负载排查实战:Load Average 飙升但 CPU 使用率低的完整诊断指南
关键词:Linux load average 高 CPU 低、D 状态进程排查、不可中断睡眠、磁盘 I/O 阻塞、vmstat 排障、iostat 磁盘瓶颈、uptime load average 高、ps STAT D、生产服务器负载高 CPU 闲
问题背景
生产环境 4 核服务器突然响应缓慢,uptime 显示 Load Average 高达 15+,但 top 中 CPU 使用率仅 10% 左右。运维困惑:负载这么高,CPU 却很闲,问题出在哪?
核心认知:Linux Load Average 不仅统计 CPU 上运行的(R 状态)进程,还包含**不可中断睡眠(D 状态)**的进程。当进程因磁盘 I/O 阻塞陷入 D 状态时,不消耗 CPU 但会计入 Load Average,从而出现「负载高、CPU 闲」的假象。
复现步骤
# 1. 启动模拟环境(Docker)
cd scenario/2026-08-31-0000
docker compose up -d --build
docker compose exec app bash
# 2. 启动 I/O 风暴 + CPU 密集脚本
python3 /workspace/scenario/2026-08-31-0000/scripts/io_storm.py &
python3 /workspace/scenario/2026-08-31-0000/scripts/cpu_burn.py &
# 3. 等待 30-60 秒后观察
uptime
top -bn1
vmstat 1 5
ps aux | awk '$8=="D"{print}'
复现结果(关键数据)
# uptime — Load Average 飙升
load average: 26.53, 8.46, 2.98
# top — CPU idle 仍高
%Cpu(s): 80.0 us, 0.0 sy, 0.0 ni, 20.0 id, 0.0 wa
# ps — 32 个 D 状态进程
root 65 0.0 0.0 18408 11460 ? D 16:06 0:06 python3 .../io_storm.py
# vmstat — r 列 30-53, b 列 12-35, bo 高达数百万/秒
r b ... bo in cs us sy id wa st
44 25 ... 415362976 ...
30 35 ... 3329704 ...
# iostat — 磁盘 %util 高达 60-99%
Device w/s wkB/s %util
vdi 916.00 153976 99.60
根本原因
io_storm.py创建 32 个 worker 进程,每个 worker 反复执行 64MB 文件的写入、fsync()强制刷盘、读取、删除操作fsync()同步等待磁盘完成写操作,进程在等待期间进入 D 状态(不可中断睡眠)- Linux 内核将 D 状态进程计入 Load Average,导致 Load Average 飙高
- 但 D 状态进程不消耗 CPU,所以 CPU 使用率保持低位
解决办法
定位 D 状态进程:
ps aux | awk '$8 ~ /^D/ {print}'
# 或
ps aux | grep 'D' | grep -v grep
确认磁盘 I/O 是瓶颈:
vmstat 1 5 # 关注 r(运行队列)和 b(阻塞)列
iostat -x 1 2 # 关注 %util,>80% 说明磁盘饱和
修复:终止 I/O 风暴进程
pkill -f io_storm.py
验证:停止后 Load Average 逐步回落
| 时间 | Load Average |
|---|---|
| 峰值 | 26.53 |
| 停止后立即 | 24.73 |
| +15秒 | 20.14 |
| +60秒 | 11.00 |
| +3分钟 | 1.06 |
| +5分钟 | 0.36 |
Load Average 是指数移动平均,需数分钟才能完全回落,属正常现象。
经验与避坑
- Load Average 高 ≠ CPU 忙:遇到负载高先看 CPU idle 和 wa(iowait),再排查 D 状态进程
- D 状态进程是 I/O 阻塞的强信号:
ps aux中 STAT 列为D的进程通常阻塞在磁盘/网络 I/O vmstat的b列直接反映阻塞进程数,r列反映可运行进程数iostat的%util> 80% 说明磁盘接近饱和- Load Average 下降是渐进的:指数移动平均特性导致即使停掉 I/O 负载,Load Average 也需要 5-15 分钟完全归零
- D 状态进程无法被 kill:如果 D 状态进程卡住,
kill -9也杀不掉,需等 I/O 操作完成或重启系统 - 生产环境优化建议:限制 I/O 并发数、使用异步 I/O(如 io_uring)、配置 I/O 调度器、升级 NVMe SSD
相关命令速查
| 命令 | 作用 |
|---|---|
uptime | 查看 Load Average(1/5/15 分钟) |
top | 查看 CPU 使用率、进程状态(S 列) |
ps aux | 查看进程,STAT 列判断 R/D/S 状态 |
vmstat 1 5 | 查看运行队列(r)、阻塞进程(b)、I/O(bi/bo) |
iostat -x 1 2 | 查看磁盘利用率(%util)和 I/O 吞吐量 |
cat /proc/loadavg | 直接查看 Load Average 数值 |
ps -eo pid,stat,wchan,cmd | 查看 D 状态进程的等待原因(wchan) |
