Linux load average 原理与优化策略

1次阅读

load average 是单位时间内处于 r 和 d 状态的平均进程数,并非 cpu 使用率;r 进程争抢 cpu,d 进程卡在硬件等待,cpu 低而 load 高常因 d 进程堆积;应重点关注 5/15 分钟值判断趋势,结合逻辑 cpu 数(如 16 核)评估是否超阈值(>24),再用 ps、iostat、lsof 分步定位 r/d 成因。

Linux load average 原理与优化策略

load average 不是 CPU 使用率,别拿 top 里的 %Cpu(s) 直接对标

很多人一看到 load average: 4.2, 3.8, 3.1 就立刻查 %us%sy,发现才 30%,就以为“CPU 还很空闲,负载高得没道理”——这是最典型的误解。load average 统计的是单位时间内处于 R(可运行)和 D(不可中断睡眠)状态的平均进程数,不是 CPU 时间占比。

  • R 状态进程在抢 CPU:比如多个 Java 线程同时 ready,但只有 4 个物理核,就会排队,推高 load
  • D 状态进程卡在硬件等待:比如磁盘慢、NFS 挂载卡住、NVMe 驱动异常,进程进 D 后 kill 不掉,但会计入 load
  • CPU 使用率低 + load 高 = 很可能有大量 D 进程,ps -eo stat,pid,comm | grep "^D" 可快速验证

看 load 数值时,优先盯死 5 分钟和 15 分钟值,别被 1 分钟值带节奏

1 分钟 load 是指数加权移动平均,对瞬时抖动极度敏感;一个 cron 脚本扫日志、一次突发请求就能把它拉到 10+,但系统可能根本没压力。真正反映趋势的是 5 分钟和 15 分钟值——它们衰减更平缓,能过滤毛刺。

  • 如果 1m > 5m > 15m:负载在爬升,要查最近部署/定时任务/流量突增
  • 如果 1m :负载在回落,可能是刚扛过高峰,或问题已缓解
  • 判断是否真高?用 grep -c 'processor' /proc/cpuinfo 得到逻辑 CPU 数(含超线程),load 持续 > 1.5× 该值才需干预;比如 16 核机器,长期 > 24 才算危险

排查 high load 的三步定位法:先分 R/D,再筛进程,最后看资源瓶颈

直接 topP 排序看 CPU 占用,90% 的情况会漏掉真正的元凶——因为 D 进程不占 CPU 时间,却推高 load。

  • 第一步:区分负载成分 —— cat /proc/loadavg 看前三个值,再执行 ps -eo stat,pid,comm | awk '$1 ~ /^[RD]/ {print $0}' | wc -l,对比总数是否接近 load 值
  • 第二步:若 R 多 → top -H 查线程级 CPU,重点关注 javapythonnginx 等主进程下的高耗线程
  • 第三步:若 D 多 → iostat -x 1 3%utilawaitcat /proc/diskstats 查具体设备延迟,再结合 lsof +D /mnt/data 看是否有进程卡在某个挂载点

优化不是加核或降负载,而是让 R 和 D 进程“快进快出”

给 32 核机器把 load 从 25 降到 10,不代表性能变好——如果这 10 个进程每个都卡在磁盘上等 200ms,响应照样慢。关键不是减少进程数,而是缩短单个进程在队列里的停留时间。

  • R 长驻:检查是否线程池过大(如 tomcat maxThreads=500)、GC 频繁(jstat -gc <pid></pid>)、或锁竞争(perf record -e sched:sched_switch -a sleep 5
  • D 积:禁用不必要的 sync 写(如数据库 fsync=off 仅限测试)、换 NVMe 替代 SATA、避免 NFS 大文件随机读写
  • 警惕“伪优化”:改 /proc/sys/kernel/sched_latency_ns 或调 vm.swappiness 对 load 影响极小,反而可能破坏内核调度平衡

真正难的从来不是看懂 load 数字,而是分辨它背后那个 R 进程是在疯狂计算,还是在死等锁;那个 D 进程是在等 SSD 返回,还是在等远端 NFS 服务器打个喷嚏。

text=ZqhQzanResources