服务器入坑指北:负载高不等于 CPU 忙

举报
Tulpartner 发表于 2026/10/31 11:37:48 2026/10/31
【摘要】 负载很高,但 CPU 看着很闲,于是判断"机器没问题",直到服务开始超时;磁盘慢导致进程卡在不可中断状态,可常规视图里根本看不出来;每次抖动都说"再看看",始终没有一套可复用的分诊顺序。 第一件事是把"负载"这个词拆开:负载平均值里含两类——"可运行或正在运行"的进程,以"处于不可中断睡眠"的进程(后者多半卡在 I/O 上)。

负载很高,但 CPU 看着很闲,于是判断"机器没问题",直到服务开始超时;磁盘慢导致进程卡在不可中断状态,可常规视图里根本看不出来;每次抖动都说"再看看",始终没有一套可复用的分诊顺序。
第一件事是把"负载"这个词拆开:负载平均值里含两类——"可运行或正在运行"的进程,以及**"处于不可中断睡眠"的进程**(后者多半卡在 I/O 上)。所以"负载高 + CPU 闲"几乎总指向 I/O 或阻塞,而不是算力不足。
这篇给一条四步分诊顺序、三处压力指标(含两种口径),以及"占用不等于压力"这条纪律。文中不贴任何真实负载值、压力数值与核数。

先把"负载"拆开

机制上,负载平均值是按"处于运行或可运行状态的进程数"加上"处于不可中断睡眠状态的进程数"算出来的。
不可中断睡眠指的是:进程在内核里等 I/O,此时连强制信号都送不进去(这一点在《进程卡死与杀不掉的进程》里讲过)。这些进程同样被算进了负载——这就是"负载高而 CPU 却闲"的来源。
判据因此很直接:"负载高 + CPU 闲"几乎总指向 I/O 或阻塞,而不是算力不足。
顺序反了的代价:一上来就看 CPU 占用排行,结论会被引到"加 CPU"上,而真正的问题在别处。
还有一个配套指标要一起看:同一份工具还能给出"当前被阻塞、等待 I/O 完成的进程数"——它直接把"有多少进程在等盘"摆在你面前。
反过来说:负载高、CPU 也确实忙,才说明瓶颈有可能真的在算力上——这时第 3 步会落在 CPU 那一处的压力上,接下来才是"要不要设限、怎么设限"的问题。

再看"压力",而不是只看"用量"

内核会直接导出"因资源不足而停滞的时间占比",分 CPU / 内存 / I/O 三类,并且区分两种口径:

  • “至少有一些进程在停滞”:有人被挡住,但机器还在干活;
  • “所有非空闲进程同时停滞”:实际的 CPU 周期被浪费——长时间处于这个状态的工作负载被认为是 thrashing,所以内核把它单独统计、单独导出。
    为什么"全都在等"更严重:"有人在等"是局部资源紧张——大部分进程还在推进,说明系统仍在有效工作;"全都在等"是整体被拖住——没有进程在有效推进,相当于这一段时间的算力被浪费掉了。这两者要分开看,不能只看其中一个。
    另外两组读数也要用起来:
  • 几个时间窗的均值(越大越平滑)+ 累计停滞时间:累计值能抓到均值掩盖的时延毛刺——那种"每次只卡一下"的问题,均值上看不出来;
  • 一个边界:系统级别上"CPU full"没有定义(只是为兼容而报为 0)。所以读 CPU 那一项时只看 some,别把 full 为 0 当成"没压力"的证据。
    还要记住:读不到压力文件,不代表没有压力——这个能力需要内核支持,先确认本机是否提供该接口。如果启用了统一层级,每个子目录里也有同格式的三份压力文件,可以按服务层级看。
    如果确实读不到:退回到一组替代证据——负载的构成(可运行与不可中断各占多少)、设备侧延迟形态、不可中断进程数。这三样合起来,同样能回答"压力是不是落在 I/O 上"。

四步分诊顺序

  1. 时间维度:持续劣化还是周期性抖动。周期性抖动要往定时调度、备份窗口、日志切分上找;持续劣化才往容量与泄漏上找。
  2. 这是不是这台机器自己能解决的:虚拟化下的"CPU 窃取时间"高,说明宿主拿走了一部分时间——此时客户机内的任何调优都不会有效,动作只有改机型或迁移。
    反过来也要会排除:窃取时间不高时,如果压力落在 I/O 或内存上,那更可能是本机资源与负载形态的问题——宿主侧不是主要方向,这时才值得在本机继续往下查。
  3. 压力落在 CPU、内存还是 I/O 哪一处:用刚说的三处压力指标来回答。
  4. 才做进程归因:谁占用高、谁在等。
    判据:每一步都有一个明确的"出口"——第 1 步决定往哪一类原因查,第 2 步决定"要不要在本机折腾",第 3 步决定看哪一处,第 4 步才是找具体进程。跳步的典型后果就是"直接看占用排行",然后朝着错误方向优化。

占用 ≠ 压力

一个进程占用高,不一定造成别人排队;反过来,真正的排队可能由一个占用不高的进程引起——它持有资源,或者自己在等 I/O。
所以正确次序是:先看压力与延迟 → 再与基线对照 → 最后才看用量。
判据:说"有人在等",要有压力与延迟证据,不能只拿占用排行当结论。这两件事经常被混为一谈,代价是你优化了一个很忙的进程,而排队的人还在排队。

只读观测命令组

# 只读观测(负载值、压力数值与核数一律用占位符;全部只读)
# 负载,以及"当前被阻塞、等待 I/O 完成的进程数"
# 三处压力:/proc/pressure/ 下的 cpu、memory、io 三个文件
#   some = 至少有一些进程停滞的时间占比;full = 所有非空闲进程同时停滞
#   几个时间窗的均值 + 累计停滞时间(用来抓毛刺)
# 设备侧延迟形态与连接数(与压力取同一时段的基线口径)
# CPU 窃取时间(部分工具在部分内核版本不显示,可直读运行状态接口)

判据:压力接口读不到时,先确认本机是否提供这个能力,而不是直接得出"没有压力"。

现象到动作的判定表

现象 结论 动作
负载高,但 CPU 闲 多半是 I/O 或阻塞 看"等待 I/O 的进程数"与 I/O 压力
压力只在 I/O,且"所有进程同时停滞" 整体被拖住,算力被浪费 优先处理 I/O 侧——这是最紧的一档
压力只在 I/O,“有人停滞” 局部资源紧张 找到在等 I/O 的那部分进程
持续劣化 往容量与泄漏方向查 看趋势与容量,而不是逐次重启
周期性抖动 与定时调度、备份窗口、日志切分重合 错峰或限流
窃取时间高 CPU 侧不归你管 改机型或迁移,本机调优无效
没有基线 无法判断什么是"异常" 先建立最小基线,再谈调参

改完怎么验证:每项一条判据

  • 同一口径与基线对照有改善:不要跨口径比。
  • 压力指标回落:三处里你针对的那一处,some 与 full 都要看。
  • 业务侧时延指标同步改善:只看系统指标,可能"系统好看、业务仍慢"。
  • 没有为误判买单:没有盲目加 CPU,也没有去改无关参数。
  • 回滚路径:改动前记录原值。
  • 验证方式固定成一句话:同一口径下压力与业务时延同步改善、且没有误改,才算通过。

这篇不解决什么

  • 不处理 I/O 异常分支:讲《云盘变慢或报 I/O 错误时你能做什么》的那篇处理块设备与虚拟盘 I/O 侧的异常分支;本篇是通用分诊——窃取时间两篇都会用到,但结论落点不同。
  • 不决定怎么设限:讲《CPU 限制该用权重还是上限》的那篇决定怎么设限;本篇只回答压力在哪、要不要设限。
  • 不展开内存限制取舍:cgroup 内存上限与 OOM 取证属于内存维度的限制与取证;本篇只把内存压力作为三处之一。

踩坑清单

  • 负载高就说"机器没问题":负载里含不可中断睡眠,CPU 闲不代表没压力。
  • 一上来就看占用排行:方向被引到加 CPU 上。
  • 把"占用高"当成"有压力":两者不是同一件事。
  • 只看"有人在等"的口径,忽略"全都在等":最紧的一档被漏掉。
  • 只看均值不看累计值:时延毛刺全被抹平。
  • 周期性抖动去加容量:查错了方向。
  • 持续劣化当成抖动:一次次重启,趋势越来越差。
  • 没有基线就调参:改完也不知道是好是坏。
  • 忽略窃取时间:在虚拟机上白调一轮。
  • 只看系统指标不看业务侧时延:系统指标都正常,而业务还在超时。
  • 压力接口读不到就认为没压力:可能是本机没提供这个能力。
  • 把 CPU 那一项的 full 当成判据:它在系统级别上没有定义。
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。