Linux 负载高但 CPU 空闲的原因

7次阅读

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

Linux 负载高但 CPU 空闲的原因

为什么 top 显示 CPU 使用率低,但 load average 却很高

负载高而 CPU 空闲,本质是系统中有大量进程在「等待」而非「运行」。linuxload average 统计的是 **1 分钟、5 分钟、15 分钟内处于可运行状态(R)或不可中断睡眠状态(D)的平均进程数**,不等于 CPU 正在执行的指令量。

常见诱因包括:

  • D 状态进程堆积(如磁盘 I/O 卡住、NFS 挂载无响应、内核锁争用)
  • 大量进程在等待慢速设备(如机械硬盘随机读、坏块重试、远程存储超时)
  • 内存严重不足导致频繁换页,pgpgin/pgpgout 激增,I/O 阻塞加剧
  • 某些驱动或内核模块陷入不可中断等待(例如旧版 qla2xxxusb 存储驱动 bug

如何快速定位 D 状态进程和阻塞源头

先看哪些进程卡在 D 状态:

ps -eo pid,stat,comm,wchan --sort=-wchan | head -20

wchan 列显示进程正在等待的内核函数,比 STAT 更具指向性。重点关注:

  • io_schedule:通用 I/O 等待(可能是磁盘/网络存储)
  • __common_interruptnvme_irq:NVMe 设备响应异常
  • nfssvcrpc_wait_bit_killable:NFS 客户端挂起
  • ext4_writepagesxfsaild:文件系统刷脏页卡住

再查整体 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,表示大块连续内存无法分配,kmallocpage_alloc 可能被阻塞
  • dmesg -T | tail -30 查是否有 Out of memorypage allocation failurebuffer 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/ 查某进程是否持有一个已断开的网络存储 fd(如 Ceph RBD 映射设备消失)
  • kuberneteskubectl describe podEvents 是否有 FailedMountContainerCreating 卡住

真正棘手的情况往往不是 CPU 或磁盘本身坏,而是某个依赖组件(比如一个配置错误的 etcd 集群、一个未设超时的数据库连接池、一个卡在 getrandom(2) 的旧内核)让整个调用链停摆——这时候 load average 是唯一诚实的指标。

text=ZqhQzanResources