引言:Load Average 高不等于 CPU 忙
线上告警群里最常见的误判之一,就是"Load Average 高了 → CPU 爆了 → 加机器"。但很多时候,你 top 一看 CPU 明明很空闲,负载却飙到十几。这一篇把 Load Average 的来龙去脉讲透:它到底是什么、什么时候会虚高、以及如何一步步定位真正的瓶颈。
一、Load Average 到底是什么
Load Average(负载平均值)是过去 1/5/15 分钟处于 可运行态 和 不可中断睡眠态 的进程平均数量。注意是两个状态:
- R 状态(Running/Runnable):正在 CPU 上跑,或排队等 CPU 的进程
- D 状态(Uninterruptible Sleep):不可中断睡眠,通常是等磁盘 IO、等网络 IO、等锁的进程
这就是为什么负载高不一定 CPU 忙——如果一堆进程卡在 D 状态等磁盘,CPU 空闲但负载照样爆表。判断标准:负载值 ≈ CPU 核数算正常,超过核数 70% 算偏高,持续超过核数 2 倍属于严重告警。
二、第一板斧:确认 CPU 还是 IO
# 同时看 CPU 和负载top -bn1 | head -5# CPU 空闲率很高但负载很高 → 大概率不是 CPU 瓶颈# 看平均负载的三个值uptime关键判断口诀:CPU 空闲 + 负载高 = 查 IO;CPU 打满 + 负载高 = 查进程。用 vmstat 一步确认:
vmstat 1 5重点看三列:r(运行队列,等待 CPU 的进程数)、b(阻塞队列,D 状态进程数)、wa(CPU 等待 IO 的时间占比)。如果 b 和 wa 很高而 r 不高,基本可以断定是 IO 瓶颈。
三、第二板斧:定位罪魁祸首
确认是 CPU 问题后,找出吃 CPU 的进程:
top -c -o %CPU# 或ps aux --sort=-%cpu | head -15确认是 IO 问题后,找出在等 IO 的进程:
# 列出所有 D 状态进程ps -eo pid,stat,wchan:32,cmd | awk '$2 ~ /^D/'# wchan 显示进程阻塞在内核的哪个函数上,能直接看出在等什么# 用 iostat 看具体哪块盘在忙iostat -x 1iostat -x 里重点看 %util(磁盘利用率)和 await(平均 IO 等待时间)。%util 接近 100% 说明磁盘已饱和。如果所有盘都不忙,那可能是 NFS、分布式存储等网络文件系统在拖后腿——D 状态进程的 wchan 会指向网络相关函数。
四、第三板斧:分清瞬时尖峰与持续高位
Load Average 的 1/5/15 分钟三个值很有讲究:
- 1 分钟高、15 分钟低:瞬时尖峰,比如定时任务集中执行、编译、备份,通常不用太紧张
- 1 分钟低、15 分钟高:负载正在下降,说明之前的瓶颈正在缓解
- 三个值都高且接近:持续过载,必须认真对待
遇到瞬时尖峰,用 atop 或 sar -q 回看历史负载曲线,确认尖峰的时间规律:
sar -q -f /var/log/sa/sa$(date -d yesterday +%d)# 查看昨天的负载记录,配合 cron 任务时间表对照如果是 cron 集中执行导致,用 systemd-timer 的 RandomizedDelaySec 或给 cron 加随机偏移,把任务打散。
五、常见误判场景复盘
场景1:内存不足引发的"假 CPU 忙"
内存不够时,系统疯狂换页(swap in/out),CPU 大量消耗在内存回收上,表现为 CPU 高 + 负载高,但业务进程本身并不吃 CPU。此时 free -h 会看到 swap 使用量在涨。解法是加内存或优化内存占用,而不是加 CPU。
场景2:D 状态进程堆积导致负载虚高
某个进程挂起在不可中断睡眠(比如 NFS 断连、磁盘故障),负载会一直居高不下,且 kill 都杀不掉(D 状态进程无法被普通信号杀死)。此时要先恢复底层存储,再考虑重启进程。
场景3:短时高并发被误读
促销、秒杀等短时流量高峰,1 分钟负载冲到很高但 5/15 分钟正常。只要响应时间可接受,无需扩容,重点是观察 5 分钟均值是否回落。
六、结语:先定性,再定量,最后动手
排查 Load Average 的正确姿势是:先看三个时间窗口的数值判断是尖峰还是持续过载 → 用 vmstat 区分 CPU 瓶颈还是 IO 瓶颈 → 用 ps/top/iostat 定位具体进程和盘 → 最后才是扩容或优化。顺序一旦搞反,很容易加错资源,钱花了问题还在。把这套流程写进团队的故障排查手册,比任何监控大屏都管用。
评论