load average 高而 CPU 使用率低,本质是大量进程处于可运行(R)或不可中断睡眠(D)状态等待资源;常见原因包括 D 状态堆积、I/O 卡顿、内存不足换页、驱动缺陷等。

为什么 top 显示 CPU 使用率低,但 load average 却很高
负载高而 CPU 空闲,本质是系统中有大量进程在「等待」而非「运行」。Linux 的 load average 统计的是 **1 分钟、5 分钟、15 分钟内处于可运行状态(R)或不可中断睡眠状态(D)的平均进程数**,不等于 CPU 正在执行的指令量。
常见诱因包括:
-
D状态进程堆积(如磁盘 I/O 卡住、NFS 挂载无响应、内核锁争用) - 大量进程在等待慢速设备(如机械硬盘随机读、坏块重试、远程存储超时)
- 内存严重不足导致频繁换页,
pgpgin/pgpgout激增,I/O 阻塞加剧 - 某些驱动或内核模块陷入不可中断等待(例如旧版
qla2xxx或 USB 存储驱动 bug)
如何快速定位 D 状态进程和阻塞源头
先看哪些进程卡在 D 状态:
ps -eo pid,stat,comm,wchan --sort=-wchan | head -20
wchan 列显示进程正在等待的内核函数,比 STAT 更具指向性。重点关注:
-
io_schedule:通用 I/O 等待(可能是磁盘/网络存储) -
__common_interrupt或nvme_irq:NVMe 设备响应异常 -
nfssvc、rpc_wait_bit_killable:NFS 客户端挂起 -
ext4_writepages、xfsaild:文件系统刷脏页卡住
再查整体 I/O 压力:
iostat -x 1
若 %util 接近 100% 且 await > 100ms,说明设备响应慢;若 %util 低但 avgqu-sz 很高,说明请求队列积压——这往往指向后端存储问题(如 RAID 卡电池失效、JBOD 故障盘、Ceph OSD 过载)。
vmstat 和 /proc/buddyinfo 揭示的隐藏线索
vmstat 1 中持续出现高 bi(块设备输入)和 si(swap in)值,说明内存压力正转化为 I/O 压力。此时检查:
-
free -h是否Available远低于Mem:总量,且SwapFree快耗尽 -
cat /proc/buddyinfo中高阶内存(如order-10)为 0,表示大块连续内存无法分配,kmalloc或page_alloc可能被阻塞 -
dmesg -T | tail -30查是否有Out of memory、page allocation failure或buffer I/O error
特别注意:某些云环境(如 AWS EBS gp2 卷)在突发 IOPS 耗尽后会限速至基线值,iostat 看不到错误,但 await 陡升、load average 暴涨——这是典型的「无声降级」。
排查 NFS、iSCSI 或容器存储时的特殊陷阱
NFS 客户端默认使用 hard,intr,服务端无响应时进程直接卡死在 D 状态,kill -9 无效。验证方式:
-
showmount -e是否超时? -
rpcinfo -p是否返回Program not registered? - 挂载选项中是否遗漏
soft,timeo=10,retrans=3(仅限允许失败的场景)
容器环境需额外检查:
-
docker ps --format "{{.ID}}\t{{.Status}}" | grep "Up.*ago"看容器是否实际卡住而非仅状态显示正常 -
ls -l /proc/查某进程是否持有一个已断开的网络存储 fd(如 Ceph RBD 映射设备消失)/fd/ - Kubernetes 中
kubectl describe pod的Events是否有FailedMount或ContainerCreating卡住
真正棘手的情况往往不是 CPU 或磁盘本身坏,而是某个依赖组件(比如一个配置错误的 etcd 集群、一个未设超时的数据库连接池、一个卡在 getrandom(2) 的旧内核)让整个调用链停摆——这时候 load average 是唯一诚实的指标。









