第2章 方法论:先分流,再下钻,热点不是根因

第 2 章不是在讲方法名,而是在定排障顺序:先把问题写清,再决定从资源侧还是服务侧起手,用工作负载特征缩小范围,最后再把热点压成可验证的解释。

本页目录

先定顺序,再谈方法

第 2 章先把性能排查的顺序定下来:先把问题说清,再做第一轮低成本分流,然后看工作负载特征,方向缩小以后才继续下钻,最后再靠假设和验证把解释压实。

这听起来像常识,但现场里最常见的失控,恰恰就发生在这里。报警一响,有人去看 CPU,有人去翻数据库图,有人直接抓 trace。每个人都能带回一条异常,但这些异常彼此接不上。团队很忙,问题空间却没有变小。

它拦的是这种“忙碌但不收敛”的分析方式。

先把问题说清,再决定走 USE 还是 RED

USERED 都不是起手动作。它们之前还有一步更重要:先把问题写清。

至少要先固定住这几件事:

  • 慢的是谁
  • 慢成什么样
  • 从什么时候开始
  • 影响范围有多大
  • 当前更像整体退化还是局部路径异常

如果这一步没做完,后面所有人都会按自己的理解去查。有人理解成“系统资源不够”,有人理解成“某条请求慢了”,有人理解成“数据库有问题”。这时候你拿到再多图,也只是在堆噪声。

把问题写清以后,才轮到选第一跳。

如果你现在最想回答的是“底层资源里有没有谁已经形成约束”,先走 USE
如果你现在最想回答的是“服务对外体验到底坏在哪里”,先走 RED

一个偏资源体检,一个偏服务体检。它们不是同义词,也不是平行摆设。

工作负载分析的作用,是把“有异常”翻成“哪类活在出事”

只看资源,很容易得到“这里有点高”。只看服务,也容易停在“这个接口慢了”。这都还不够。

这里还要再往前走一步:看工作负载特征。

你最终要分清的,往往不是“系统是不是有问题”,而是:

  • 是总量上来了,还是某一类请求变坏了
  • 是短时尖峰,还是稳定持续的压力
  • 是资源不够,还是路径本身太长

很多现场最后查出来,问题不在资源打满,而在请求形状变了、访问模式变了、上游行为变了。工作负载没看清,后面的资源分析经常只是在看显影。

几毫秒通常已经不是 CPU 世界

这里还有一层很重要:时间量级直觉。

原书用过一组很夸张但很有效的比例:把 1 个 CPU 周期 想成 1 秒,那么 L1 访问只有几秒,主存访问已经是几分钟,SSD I/O 变成几十小时,机械磁盘 I/O 更是长到按月算。

这组数字不是拿来当记忆题的,而是用来改掉一个特别顽固的误判:一看到慢,就先怀疑 CPU。

如果一个操作已经慢到毫秒级,它通常已经越过了纯 CPU 执行时间,更像是等待、I/O、网络、锁竞争,或者跨层排队的问题。更稳的动作是:

先看这个耗时大概落在哪个量级,再决定下一跳该进 CPU、I/O、网络,还是先查等待路径。

没有这层直觉,很容易一开始就钻错层。

高使用率不够,排队才更像约束

第 2 章反复在纠正一个误会:忙,不等于卡死。

utilization 最多先说明资源很忙,但性能问题真正更接近 saturation,也就是新的工作已经进不去,只能开始排队。

所以看到 100% 还不够。你还得继续问:

  • 有没有队列在拉长
  • 有没有等待时间在上升
  • 有没有新工作已经开始挨饿

CPU 就是很典型的例子。高 CPU 使用率先说明它正在做工,真正更有解释力的,是线程是不是已经开始抢 CPU、等 CPU。可以先看 vmstat 1 里的运行队列,也可以看 /proc/pressure/cpu 里的压力。

磁盘也一样。%util 能说明设备一直在忙,但不能单独证明它已经顶死。更该看的是 iostat -x 1 里的 aqu-sz、I/O 压力、延迟和吞吐是不是一起恶化。

这里更该记住的不是“使用率有欺骗性”,而是:更接近性能问题的,往往不是忙碌本身,而是排队已经开始发生。

USE 这个名字本身,会把人带偏

USE 这个名字本身就很容易把动作顺序带偏。

字面上看像是 Utilization -> Saturation -> Errors,但现场更稳的顺序经常正好反过来:

  1. 先看 Errors
  2. 再看 Saturation
  3. 最后才看 Utilization

原因不复杂。

错误最直接,能最快帮你排掉硬故障。
饱和更接近“为什么慢”,因为只要已经出现队列、等待时间或 PSI 压力,约束方向就很清楚了。
使用率当然还要看,但它更像背景信号,告诉你资源有多忙,而不是单独替你下结论。

如果把顺序反过来,先盯着使用率,很容易又掉回“看到 100% 就宣布根因”的老坑。

热点最多是线索,不是根因

另一种很常见的错法,是把热点直接升级成根因。

热点当然重要,它至少说明这里值得继续看,也可能和当前症状有关。但它还不能单独说明三件事:

  • 为什么这里会形成约束
  • 它是根因、连锁反应,还是旁观者现象
  • 如果改这里,症状会不会真的消失

“哪里热”和“为什么慢”之间,还隔着一层解释工作。通常还得补等待证据、路径证据、前后对照,或者反向排除。

没有这层补充,热点只能算线索,不能算结论。

证据解释不了因果时,就该换挡

很多排障之所以越看越乱,不是因为看得太少,而是因为一直在看同一类证据。

下面这些时刻,通常都说明该换挡了:

  • 你只能说“这里有异常”,但说不出“为什么异常会形成”
  • 你已经知道大概在哪一层,却还不知道是哪条路径在制造等待
  • 你已经拿到热点,但热点和整体症状还接不成闭环
  • 你继续看同一类图,只是在重复确认自己已经知道的东西

这时候别硬挖。该换更聚焦的 profile、trace、路径证据,或者干脆回退重做分流。

工具切换,本质上不是“上更高级的工具”,而是证据升级。

这章最后应该留下什么

读完这章,至少该留下这 5 条:

  1. 先把问题写清,再选第一跳。
  2. USE 看资源体检,RED 看服务体检,别混着用。
  3. 工作负载分析要回答“哪类活在出事”,不只是“哪里有点高”。
  4. 高使用率不够,排队和等待才更像约束。
  5. 热点不是根因,证据不够就换挡。

拿着这 5 条回头看,方法论就不再只是抽象框架,而更像一套能压住现场混乱的起手纪律。

第 3 章接着解决的是另一个问题:这些证据到底落在哪一层。顺序定完以后,还得把系统地图立住,不然你仍然可能把一路显影看成几个独立问题。