朕喜技术(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

根本原因

  1. io_storm.py 创建 32 个 worker 进程,每个 worker 反复执行 64MB 文件的写入、fsync() 强制刷盘、读取、删除操作
  2. fsync() 同步等待磁盘完成写操作,进程在等待期间进入 D 状态(不可中断睡眠)
  3. Linux 内核将 D 状态进程计入 Load Average,导致 Load Average 飙高
  4. 但 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 是指数移动平均,需数分钟才能完全回落,属正常现象。

经验与避坑

  1. Load Average 高 ≠ CPU 忙:遇到负载高先看 CPU idle 和 wa(iowait),再排查 D 状态进程
  2. D 状态进程是 I/O 阻塞的强信号:ps aux 中 STAT 列为 D 的进程通常阻塞在磁盘/网络 I/O
  3. vmstat 的 b 列直接反映阻塞进程数,r 列反映可运行进程数
  4. iostat 的 %util > 80% 说明磁盘接近饱和
  5. Load Average 下降是渐进的:指数移动平均特性导致即使停掉 I/O 负载,Load Average 也需要 5-15 分钟完全归零
  6. D 状态进程无法被 kill:如果 D 状态进程卡住,kill -9 也杀不掉,需等 I/O 操作完成或重启系统
  7. 生产环境优化建议:限制 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)

版权声明

本文为博主原创文章,遵循 CC BY-NC-SA 4.0 许可协议。 转载请注明出处:http://localhost/blogs/2026-08-31-0012-linux-load-average-io-blocking

分享这篇文章