什么是 Load(负载)?

#计算机网络#操作系统#面试八股

什么是 Load(负载)?

Load(平均负载,load average)是一段时间内系统"想跑但没在跑"的任务数平均值, 统计口径是"可运行状态(R) + 不可中断睡眠状态(D)"的任务数,按 1、5、15 分钟做指数衰减平均。 它衡量的是需求侧的排队长度,不是 CPU 的忙碌程度——这也是 load 与 CPU 利用率最容易被混淆的地方。

1. 内核怎么算

内核每 5 秒(LOAD_FREQ)采样一次 nr_running + nr_uninterruptible,然后做指数衰减累加:

load(t) = load(t-1) × e^(-5/60)  +  n × (1 - e^(-5/60))     // 1 分钟
窗口每次衰减系数 e^(-5/T)含义用途
1 分钟≈ 0.9200最近一分钟的瞬时压力看突发
5 分钟≈ 0.9835中短期趋势看是否持续
15 分钟≈ 0.9945长期水位看整体容量
load
 8 ┤                    ╭─╮
 6 ┤              ╭─────╯ ╰╮
 4 ┤        ╭─────╯        ╰──╮
 2 ┤────────╯                 ╰────    ← 15 分钟曲线最平滑
   └──────────────────────────────► t
     1min 曲线抖,15min 曲线滞后

因为是指数平均,单次尖峰会被抹平;反过来说,一次持续十分钟的拥堵,1 分钟值早就掉下来,15 分钟值还在高位。

2. 怎么读这个数

观察值结论
load < 核数有余量,但要看趋势
load ≈ 核数基本跑满,没有排队
load > 核数有任务在排队,具体要看是 R 还是 D
load 持续下降压力在缓解
三个值一起涨负载是持续性的,不是瞬时尖峰

关键换算:load 要除以核数再看。8 核机器 load=8 是满载,load=16 意味着平均每个任务要等一轮; 而 1 核机器 load=2 就已经在排队了。

3. 采集与判断

cat /proc/loadavg        # 0.52 0.58 0.59 1/1234 56789
                         # 运行中/总任务数、最近创建的 PID
uptime                   # load average: 0.52, 0.58, 0.59
nproc                    # 核数

# 谁在排队:R 是多,还是 D 多
ps -eo state,pid,comm | awk '$1=="R" || $1=="D"' | head
// 把 load 归一化成"每核排队数",方便告警
raw, _ := os.ReadFile("/proc/loadavg")
f := strings.Fields(string(raw))
l1, _ := strconv.ParseFloat(f[0], 64)
cores := runtime.NumCPU()
fmt.Printf("load1=%.2f cores=%d per-core=%.2f\n", l1, cores, l1/float64(cores))

4. 常见追问

Q:为什么 D 状态(不可中断睡眠)也算进 load? 因为 D 状态通常卡在磁盘 IO、NFS、驱动等关键路径上,任务"想跑但跑不了",和 R 一样构成系统瓶颈。 内核故意把它计入,正是为了让"IO 卡死"也能体现在 load 上。代价是 load 高不一定 CPU 忙。

Q:load 高但 CPU 利用率很低,怎么排查? 先看 D 状态任务数:ps -eo state,pid,wchan,comm | grep '^D' 看卡在哪个内核函数; 再看 iostat -x 1 的 %util 与 await;最后看是否 NFS/网络存储超时。 这类"load 高 CPU 闲"几乎都是 IO 或锁等待。

Q:容器里看到的 load 是谁的? 默认是宿主机的 /proc/loadavg,容器之间共享,所以在容器里看 load 经常失真。 需要隔离时用 lxcfs 挂载或直接采 cgroup v2 的 cpu.stat(nr_running、nr_throttled)。

Q:load 和"运行队列长度"是一回事吗? 接近但不完全。/proc/stat 的 procs_running 是当前瞬时运行队列长度,load 是它的历史平均值, 再加上了 D 状态任务。瞬时值抖得厉害,平均值才适合做容量规划。

小结

load = R + D 任务数的指数滑动平均,回答"有多少活想干",不回答"CPU 干了多少"。 使用时永远先除以核数,再看 R 与 D 的构成。load 高而 CPU 低,八成是 IO 阻塞; load 高且 CPU 高,才是真算力不足需要扩容。

笔记加载中…