USE 方法 · 资源的三个信号,精髓在饱和度

Utilization、Saturation、Errors —— Brendan Gregg 的资源监控方法论。这一章讲清三者的区别、为什么「饱和度」才是精髓(使用率 100% 不一定有问题,饱和度 > 0 一定有),并给出 CPU/内存/磁盘/连接池的具体 PromQL。

作者 David更新于 第 15 篇(共 52 篇)

USE 方法 · 资源的三个信号,精髓在饱和度

RED 测服务,USE 测资源。它由性能大师 Brendan Gregg 提出,针对每一类资源问三个问题:

信号全称问题
UUtilization使用率:忙的时间占比(或已用容量占比)
SSaturation饱和度:排队的程度——有多少工作在等
EErrors错误:这个资源报了多少错

精髓在 S。 这一章讲清为什么。

使用率 ≠ 有问题

最反直觉、也最重要的一条:使用率 100% 不一定有问题;饱和度 > 0 几乎一定有问题。

想象一个收银台:

  • 使用率 100% —— 收银员一刻不停在扫码。这是好事! 说明资源被充分利用,没浪费。只要没人排队,顾客体验完美。
  • 饱和度 > 0 —— 有人在排队。这一刻起,顾客开始等待——延迟产生了。

使用率衡量“资源在忙吗”,饱和度衡量“有人在等吗”。用户感知的是后者,不是前者。

这解释了一个常见的错误认知:很多团队看到“CPU 90%”就紧张,看到“CPU 40%”就放心。但真相是:

  • CPU 90% 但 load 很低、没有排队 —— 系统跑得很好,资源利用充分。恭喜,你的钱花得值。
  • CPU 40% 但线程都堵在锁上 —— CPU 闲着,但请求全在排队。用户体验已经崩了,而你的 CPU 面板一片绿。

只看使用率会同时导致误报和漏报。 这就是 USE 把饱和度单列为一个一等信号的原因——它是最接近用户痛苦的资源指标。

各类资源怎么测

USE 的用法是:列出你所有的资源,给每个都填这三格。

资源UtilizationSaturation ★Errors
CPU非空闲时间占比run queue 长度 / load(罕见)机器校验错
内存已用 / 总量swap 换页、OOM kill 次数OOM
磁盘 IO设备忙时占比IO 队列深度、awaitIO 错误
网络带宽占比丢包、重传、队列溢出网卡错误
连接池已用连接 / 上限等待连接的线程数 / 等待时长 ★获取连接超时
线程池活跃线程 / 上限队列里排队的任务数 ★拒绝的任务数

表里打 ★ 的那两行(连接池、线程池)最值得注意——它们是应用层的资源**,而且是最常见的隐形瓶颈。**

很多“服务变慢”的事故,机器指标全是绿的(CPU 30%、内存 50%、磁盘闲),但数据库连接池满了,所有请求都在排队等连接。这时:

  • Utilization = 100%(连接都被占着)
  • Saturation = 一堆线程在等 ← 这才是用户感受到的那 2 秒
  • 而 CPU/内存/磁盘 全部正常

如果你只对机器资源做 USE、不对应用层资源做,这类故障你会完全瞎掉。 连接池、线程池、队列、信号量、限流器——任何“有容量上限、会被占用、会让人排队”的东西都是资源,都该上 USE。

实战建议:连接池的“等待时长”是最有价值的单个指标之一。 它直接等于“用户为了拿到一个连接而多等的时间”。很多连接池库(HikariCP、Go 的 database/sql)都能吐这个,务必采它。

具体 PromQL(可以直接抄)

基于 node_exporter 的常用查询:

# ── CPU ──
# U:使用率(非 idle 时间占比)
1 - avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m]))

# S:饱和度 —— load 除以核数(> 1 表示有排队)
node_load5 / count by (instance) (node_cpu_seconds_total{mode="idle"})

# ── 内存 ──
# U:使用率
1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)

# S:饱和度 —— 换页速率(> 0 就该警觉)
rate(node_vmstat_pswpin[5m]) + rate(node_vmstat_pswpout[5m])

# ── 磁盘 IO ──
# U:设备忙时占比
rate(node_disk_io_time_seconds_total[5m])

# S:饱和度 —— 加权 IO 时间(反映队列深度)
rate(node_disk_io_time_weighted_seconds_total[5m])

# ── 网络 ──
# S:饱和度 —— 丢包
rate(node_network_transmit_drop_total[5m]) + rate(node_network_receive_drop_total[5m])
# E:错误
rate(node_network_transmit_errs_total[5m]) + rate(node_network_receive_errs_total[5m])

注意 CPU 饱和度那条:node_load5 / 核数。 load 是个容易被误读的指标:

  • Linux 的 load 包含 D 状态(不可中断睡眠,通常是等 IO)的进程,不只是等 CPU 的。所以 load 高不一定是 CPU 忙,可能是磁盘慢——这是个经典的误诊来源。
  • load / 核数 > 1 只是粗略说明“排队了”。更准确的 CPU 饱和度应该看 PSI(Pressure Stall Information,/proc/pressure/cpu),它直接告诉你“因为等 CPU 而损失的时间占比”——这正是饱和度的精确定义。较新的 node_exporter 支持 node_pressure_cpu_waiting_seconds_total,有的话优先用它。
# 更好的 CPU 饱和度:PSI(因等 CPU 而停顿的时间占比)
rate(node_pressure_cpu_waiting_seconds_total[5m])

USE 的落地清单

Gregg 给的用法是一张表**,不是一堆面板:列出每个资源,逐格填。填不出来的格子,就是你的监控盲区。**

资源          U        S        E
─────────────────────────────────
CPU           ✅       ✅       -
内存          ✅       ✅       ✅
磁盘          ✅       ✅       ✅
网络          ✅       ❓ ←盲区!  ✅
DB 连接池     ✅       ❓ ←盲区!  ✅
线程池        ❓       ❓ ←盲区!  ❓

这张表的价值在于它让“盲区”显式化。 大多数团队做完这张表会发现:机器资源填得挺满,应用层资源(连接池、线程池、队列)几乎全是问号——而那恰恰是最常出事的地方。

先把 ★ 那几个饱和度补上,收益立竿见影。

RED 和 USE 怎么配合

图表加载中…

典型排障流:RED 告诉你“服务出问题了” → USE 告诉你“是哪个资源的锅”。**

注意最后那个分支:所有资源都没饱和,但服务就是慢 → 说明瓶颈不在本服务,而在下游(数据库、依赖服务、外部 API)。这时你要去看下游的 RED——于是递归下去,直到找到那个真正饱和的资源。

RED 是“症状”,USE 是“病因”;RED 沿调用链递归,USE 在每一跳落地。这两套配合,构成了一个可机械执行的排障算法——不用灵感,顺着查就行。

小结与下一章

USE = Utilization、Saturation、Errors,对每一类资源问这三个问题。精髓是饱和度:使用率 100% 不一定有问题(资源充分利用是好事),饱和度 > 0 几乎一定有问题(有人在排队 = 用户在等)——只看使用率会同时误报和漏报(CPU 90% 无排队 = 很健康;CPU 40% 全堵在锁上 = 已崩但面板全绿)。关键盲区是应用层资源(连接池 / 线程池 / 队列)——机器指标全绿而连接池排满是最常见的隐形事故,连接池等待时长是最有价值的单个指标之一。CPU 饱和度用 load/核数 只是粗略(load 含 D 状态进程,高不一定是 CPU 忙),有 PSI 优先用 PSI。USE 的用法是一张表,让盲区显式化。配合上:RED 是症状(服务出事了),USE 是病因(哪个资源的锅);都没饱和 → 瓶颈在下游,递归查下游的 RED。

第三套方法论来自 Google SRE,和 RED 高度重叠但视角不同。下一章讲清它们的关系。👉 四大黄金信号。

参考资料

  • [1] Brendan Gregg「The USE Method」及《Systems Performance》。
  • [2] Linux PSI(Pressure Stall Information)文档;node_exporter 指标参考。
  • [3] 关联RED 方法、常见指标范围。

本页目录