这一章在做什么

这一章不讲具体工具,讲排查的思路和读数的常识。思路是一组方法:先把问题说清楚,用 RED 看服务、用 USE 扫一遍资源,分清是负载太大还是实现有毛病,再沿着延迟一层层往下拆,每一步都用假设和测试来验证。常识是几个最容易读错的数:利用率和饱和度不是一回事;排队让延迟在利用率远没到 100% 时就变陡;平均值会把分布藏起来。后面各章的「方法」一节,都是这里在某种资源上的具体化。

一次排查的四段路,每段用什么方法 起步 问题陈述 把「慢」换成一个数 定方向 RED:负载还是服务 USE:哪个资源 往下挖 负载特征 下钻、延迟分析 收尾 量化收益 决定停不停 每一步都是:提出假设 → 做出预测 → 观测或实验 → 分析(科学方法) 要避开的三种反方法:只用熟悉的工具(路灯)、随手乱改参数、没有数据就推给别的团队 节号:§2.5.5 → §2.5.9–§2.5.13 → §2.8.1、§2.3.6;科学方法 §2.5.6
本站画的示意,按「一次排查从头到尾」重新组织了书里 §2.5 的方法。书里没有规定这样的总顺序,只说问题陈述应当第一个用、USE 方法要在排查早期用。

什么时候翻这一章

这一章是全书的总纲:第 5–10 章各有一节 Methodology,在应用、CPU、内存、文件系统、磁盘、网络上重讲 USE、负载特征、静态调优;第 12 章接着讲基准测试。遇到具体资源的问题,先在这里定好思路,再去对应的章找工具。

先用中文过一遍

延迟、利用率、饱和度:最常用也最常读错的三个数

响应时间(response time)是一个操作从发出到完成的全部时间,等于排队等待加上真正被处理的服务时间(service time)。延迟(latency)这个词有两种用法:严格说是「等着被处理」的那一段,日常又常指整个响应时间(§2.1、§2.3.1)。所以说延迟时要带上量的是哪一段:DNS 解析、TCP 建连、请求处理。延迟好用,是因为它的单位是时间,可以相加、可以比较:「每秒 100 次网络 IO」和「每秒 50 次磁盘 IO」比不出谁更伤,换成「每秒在网络上等了 100 ms、在磁盘上等了 50 ms」就一目了然。

利用率(utilization)在这本书里多数时候指按时间算的:一段时间里,这个资源有多少时间在忙(§2.3.11)。它有两个坑。第一,能同时处理多个请求的东西(SSD、存储阵列、八个工作线程的线程池),「100% 的时间都在忙」不等于「再也接不下活」,后者是按容量算的利用率。内存这类按容量计的资源用的就是后一种定义。第二,利用率永远是某个时间段的平均:一分钟平均 40%,可能藏着几秒钟的 100%。

饱和度(saturation)问的是:有多少活已经来了,却因为资源被占着只能排队(§2.3.12)。排队就意味着有人在等,所以书里的态度是任何程度的饱和都值得看。按时间算的利用率没到 100% 时也可能已经有排队,下面「排队」那一节会算给你看。

一分钟里每秒的利用率:平均 40%,中间有 6 秒是满的 这 6 秒满了,新请求只能排队(饱和) 平均 40% 100% 0 第 0 秒 第 60 秒 按分钟取平均只剩一个 40%,看不出排队。要看饱和,用短间隔,或者直接看排队类的指标。
本站画的示意,数字是编的。书里讲过一个真实的例子:客户的监控是 5 分钟平均,CPU 从没超过 80%,实际却有几秒几秒的 100% 和调度排队(§2.8.2)。

USE 和 RED:一个站在机器里,一个站在服务门口

USE 方法一句话就能说完:对每一个资源,查利用率(Utilization)、饱和度(Saturation)、错误(Errors)(§2.5.9)。它的力量在「每一个」:先列资源,再为每个资源找指标,而不是先打开手头的工具看它显示什么。这样一来,找不到工具回答的问题也会留在清单上,成为「已知的未知」(§2.3.15),而不会因为没有工具就被忘掉。查的顺序是先错误(客观,最快排除)、再饱和(不为零就值得看)、最后利用率。三项都正常也有用:可以比较放心地说「不是这个资源」,把范围缩小。

「资源」不只是 CPU、内存、磁盘、网卡。书里把软件资源也算进来:一把互斥锁,持有的时间是利用率,排队等它的线程是饱和度;一个线程池,工人忙的时间是利用率,排着等工人的请求是饱和度;进程数、文件描述符的上限用光了,报错就是错误。容器里的 cgroup 限额也一样能套上去。

RED 方法是 Tom Wilkie 为微服务提出的:对每一个服务,查请求率(Rate)、错误(Errors)、耗时(Duration),耗时要看分布而不只看平均(§2.5.10)。书里说两者互补:USE 看机器的健康,RED 看用户感受到的健康。RED 里的请求率还是一条早期线索:请求率没变而耗时涨了,问题多半在服务自身;两个一起涨,先怀疑负载(§2.3.8)。

RED 站在服务门口量,USE 站在机器里量 客户端 请求 你的 C++ 服务 请求率 · 错误数 · 耗时的分布 在入口处量,每个服务一组 用户感受到的健康 RED,§2.5.10 CPU利用 · 饱和 · 错误 内存利用 · 饱和 · 错误 磁盘利用 · 饱和 · 错误 网卡利用 · 饱和 · 错误 锁、线程池软件资源也算 机器的健康:每个资源依次查错误、饱和度、利用率(USE,§2.5.9) 锁:持有时间算利用率,排队等锁的线程算饱和度;线程池同理
本站画的示意。一次排查里两者都用:RED 告诉你「用户那边坏了没有、是不是流量变了」,USE 告诉你「机器上哪个资源扛不住了」。

排队:为什么不用等到 100%

把一个处理线程、一块磁盘、一把锁都看成一个服务台:请求按平均速率 λ 到达,每个请求要占用它 S 的时间。利用率就是 ρ = λ × S:每秒来 600 个、每个 1 ms,ρ 是 0.6。排队论(queueing theory)回答的是:ρ 涨上去,平均要等多久(§2.6.5)。

答案取决于到达和服务时间有多随机。书里用 Kendall 记法写成「到达/服务/服务台数」:M 表示随机(指数分布),D 表示固定。两个最常用的单服务台模型:

代几个数(S = 1 ms):M/D/1 在 60% 是 1.75 ms,约 67% 正好翻倍到 2 ms,80% 是 3 ms;M/M/1 在 60% 已经是 2.5 ms,80% 是 5 ms。书里的说法是过了六成平均响应时间就到两倍上下、八成到三倍,所以磁盘这类请求通常一旦开始就不能被打断、只能排队等的资源,远没到 100% 就会成为问题;CPU 不同,高优先级的工作可以抢占。书里还提醒:M/D/1 在某种意义上是最好的情况,服务时间一有波动,平均值就更高;p90、p99 过了六成以后恶化得比平均值快得多。

另一个随手能用的工具是 Little 定律(Little’s law):系统里平均的请求数 L = 到达率 λ × 每个请求在系统里的平均时间 W。每秒 800 个请求、平均 5 ms,系统里平均就有 4 个请求在处理或排队。拿它可以从监控里的两个数推出第三个,或者核对线程池、连接池该开多大。

一个处理线程:每个请求固定花 1 ms,每秒来 600 个 到达 λ = 600 个/秒 队列:平均 0.45 个,时有时无 处理 S = 1 ms 完成 利用率 ρ = λ × S = 600 × 0.001 s = 0.6 服务时间固定(M/D/1):平均等 0.75 ms,响应 1.75 ms 到达、服务都随机(M/M/1):平均等 1.5 ms,响应 2.5 ms Little 定律:系统里平均有 L = λ × W = 600 × 1.75 ms ≈ 1.05 个请求 流量涨到每秒 800 个(ρ = 0.8):固定的响应 3 ms,随机的 5 ms。流量涨三成,等待翻倍以上。
本站画的示意和算例。公式只对「单个服务台、队列不封顶、长期平均」成立;真实服务的到达常常一阵一阵的,比这里更糟。下面的模拟器可以拖着利用率看这两条曲线。

平均值、百分位和多峰分布

平均值把一组数压成一个数,最常用的是算术平均。另外两种各有用处(§2.8.2):几何平均适合把几层各自的提速倍数合起来;调和平均适合求速率的平均。比如下载 1000 MB,前 200 MB 是 100 MB/s,后 800 MB 被限到 20 MB/s,总共用 2 + 40 = 42 秒,平均是 1000 / 42 ≈ 24 MB/s,而不是 (100 + 20) / 2 = 60。负载平均那种衰减平均(decayed average)给近期更大的权重,细节在 §6.6.1。

描述分布要用别的数(§2.8.3、§2.8.4):标准差说明离散程度,单看说明不了多少,除以平均值得到变异系数才好比较;百分位说明「最慢的那一小撮」有多慢,p50 就是中位数,p99 是 99% 的请求都比它快的那个值,SLA 里也可能写 p99 或 p99.9。

可这些数默认分布只有一个峰。系统里的延迟却经常是两个峰:缓存命中很快、未命中很慢;走快路径很快、走慢路径很慢(§2.8.5)。这时平均值落在两个峰之间,那里可能一个请求都没有。还有极少数特别慢的离群值(outlier),除了最大值几乎什么指标都看不出它们(§2.8.6)。办法是直接看完整的分布:直方图、热图(§2.10.3)。

带本地缓存的查询服务:一分钟内请求延迟的直方图 中位数 0.9 ms 平均 3.2 ms:这附近几乎没有请求 p99 10 ms 命中 65% 未命中、回源 35% 0 4 ms 8 ms 12 ms 平均值落在两个峰之间:没有哪个请求花了 3.2 ms,中位数也只说出了快的那一半。
本站画的示意,数据是编的。遇到这种形状,该问的是未命中占多少、未命中那条路为什么慢,而不是怎么把「平均」往下压。第 8 章的模拟器可以调命中率看双峰怎么变。
英文中文一句话
response time响应时间排队等待加服务时间,操作从发出到完成的全部时间 §2.1 术语页
latency延迟严格说是等待的那段,也常指整个响应时间;说清量的是哪一段 §2.3.1 术语页
service time服务时间请求真正被处理的时间,不含排队 §2.1
utilization利用率一段时间里资源忙的比例;能并行的设备忙满不等于满载 §2.3.11 术语页
saturation饱和度来了却只能排队的工作,书里也叫 pressure §2.3.12 术语页
bottleneck瓶颈限制整个系统性能的那个资源 §2.1
USE methodUSE 方法对每个资源查利用率、饱和度、错误 §2.5.9 术语页
RED methodRED 方法对每个服务查请求率、错误、耗时 §2.5.10 术语页
workload characterization负载特征分析只看输入,描述施加在系统上的负载,而不是它表现得怎样 §2.5.11 术语页
drill-down analysis下钻分析从高处看起,丢掉无关的部分,往有意思的地方一层层挖 §2.5.12
knee point拐点扩展曲线从线性变成受竞争限制的那个点 §2.3.9
Little’s lawLittle 定律系统里的平均请求数 = 到达率 × 平均停留时间 §2.6.5 术语页
M/M/1, M/D/1排队模型Kendall 记法:到达/服务/服务台数,M 随机、D 固定 §2.6.5
percentile百分位p99 是 99% 的值都不超过它的那个数,量最慢的那一小撮 §2.8.3 术语页
multimodal distribution多峰分布有两个以上的峰,平均值和标准差都会误导 §2.8.5 术语页

方法:按什么顺序查

书里只定了两条顺序:碰到新问题,第一个用问题陈述(§2.5);USE 方法要在排查早期用,先把系统性的瓶颈找出来(§2.5.9)。其余方法按情况取用。本站把它们排成一次排查的七步,前三步不需要任何特殊工具,十几分钟就能做完;第 4、5 步才开始用到后面各章的剖析和跟踪工具。

  1. 问题到底是什么?

    先别急着登录机器。把「慢」翻译成一个能量的数:哪类请求、看平均还是 p99、从多少变成了多少;再问它以前快过没有、最近变过什么(代码、配置、内核、流量、机器)。书里把这一步放在所有方法之前,作者说过有时只靠问话就在电话里把问题解决了。§2.5.5

  2. 负载变了,还是服务变了?

    拉出这个服务的请求率、错误数和耗时分布(RED)。请求率平稳而耗时上升,问题多半在服务自身:实现、配置、依赖、它用的资源;请求率和耗时一起涨,先当负载问题,转第 4 步看压力从哪来。C++ 服务可以从接入日志或已有的指标里取每秒请求数和 p50、p99。§2.5.10§2.3.8

  3. 哪个资源扛不住了?

    USE:列出资源(CPU、内存、网卡、磁盘,加上线程池、锁、文件描述符这些软件资源,容器里还有 cgroup 限额),每个依次查错误、饱和度、利用率。书里说最常见的问题往往出在最好查的几项上:CPU 饱和、内存不够、网卡跑满、磁盘忙。起步的命令可以照 §1.10.1 的「60 秒」清单,Linux 上逐项的指标在附录 A。查不到的指标记下来。§2.5.9§1.10.1

  4. 压力从哪来、长什么样?

    负载特征:谁在压(进程、用户、客户端 IP),为什么(调用栈),压的是什么样(读写比、大小、频率,连同它的波动),随时间怎么变(有没有日周期)。答案再显然也查一遍,书里的例子是本以为只有自家 Web 服务器在连数据库,一查是整个互联网在打。最大的收益来自去掉不该有的工作:死循环的线程、重试风暴、高峰时段的备份;去不掉就限流、挪到低峰。§2.5.11§2.5.20

  5. 时间花在哪一段?

    下钻和延迟分析:拿一个慢请求,把时间一分为二,追大的那一半,再分。典型的几刀是:在 CPU 上还是不在(第 5、6 章的 CPU 剖析和 off-CPU 分析),不在时是等锁还是等 IO,IO 时间是在排队还是在被服务。拆到能动手为止;逼自己多问几次「为什么」。汇总值把细节抹掉时,用事件跟踪一个一个地看。§2.5.12§2.5.13§5.4.2§2.5.15

  6. 猜得对吗?

    每个怀疑都写成「假设 + 预测」再去验证:观测(量一量,预测的数对不对)或实验(改一处,预测会变好还是变坏)。实验一次只改一个因素,没效果就先改回去再试下一个;故意让它变差也是一种验证。从假设到数据的来回越快,错的猜测死得越早。§2.5.6§2.5.7

  7. 修好能快多少?什么时候停?

    用时间估收益:请求 12 ms,可优化的那段占 3 ms,就算降到零也只快 1.3 倍。修完用同一个指标比前后,看分布而不只看平均。已经解释了大部分的变慢,或者再挖下去的成本超过收益,就停。什么都没找到时,不加负载把配置静态地过一遍:版本、协商速率、调试开关、快满的文件系统。§2.8.1§2.3.6§2.5.17

第 5 步:把一个 40 ms 的慢请求一刀刀拆开(数字是编的) 一个请求:40 ms CPU 6 ms 不在 CPU 上:34 ms 锁 4 等读文件:30 ms 在设备队列里排队:22 ms 设备服务 8 ms 每一刀只问一个二选一的问题,追大的那一半。最后一刀说明慢在排队,不在设备本身。
本站画的示意。最后一刀的结论把方向转回第 3、4 步:排队说明这块盘被压得太满,该查是谁在压它,而不是换更快的盘。

反过来,有三种做法书里叫「反方法」,排查时发现自己在这么做就该停一下:只跑自己熟悉的工具,因为那里「亮」(路灯效应);随手改参数看看会不会好;没有数据就把问题推给网络组、存储组。第一种即使找到了问题,也可能是「一个」问题而不是「那个」问题;第二种既慢,又会留下没人说得清的配置。

动手:模拟器

先猜:一个每次固定花 1 ms 的处理线程,利用率从 30% 升到 60%,平均响应时间涨多少?升到 90% 呢?再把服务时间换成随机的(有的请求快、有的慢,平均还是 1 ms),同样 60% 的利用率,等待会变成几倍?拖动滑杆或点下面的按钮验证。

模拟器

利用率与排队延迟

一个服务台,平均服务时间 S = 1 ms。拖利用率,看平均等待、平均响应和队列长度怎么变;切换「到达和服务都随机」(M/M/1)和「服务时间固定」(M/D/1)。上面的曲线按公式算,下面是用带种子的随机数实际模拟 1.8 万个请求的结果。

2 × 服务时间 0 4 8 10 0% 20% 40% 60% 80% 100% 利用率 ρ 平均响应时间(ms) 到达和服务都随机(M/M/1) 服务时间固定(M/D/1) — —

按公式,此刻平均在排队的请求(每格一个,不含正在处理的那个)

模拟:连续 150 个请求各自的响应时间(橙色是超过平均 3 倍的)

—
拖动利用率,或者点一个百分比。
—
平均排队等待(公式)
—
平均响应时间(公式)
—
平均排队长度(公式)
—
模拟的平均响应
—
模拟的 p99
  1. 选「服务时间固定」,点 60% 和 80%:平均响应是 1.75 ms 和 3 ms。翻倍的点在哪?把滑杆慢慢往右拖,看 2 × 服务时间那条虚线在约 67% 处被穿过。§2.6.5
  2. 停在同一个利用率,来回切换两种模型:排队等待正好差一倍。服务时间本身的波动也在制造排队。想想你的服务:请求处理时间越不均匀(有的 0.1 ms、有的 20 ms),同样的 CPU 利用率下排得越久。
  3. 拖到 90%,选「到达和服务都随机」,点几次「换一批随机数」:模拟的平均值和公式差多少?下面那排柱子里最高的是平均的几倍?高利用率时队列一旦排起来要很久才消掉,短时间量出来的数本来就不稳,p99 更是如此。§2.8.3

分节地图

这一章分三块:背景(§2.1–2.4)、方法(§2.5–2.7)、指标(§2.8–2.10)。先读的是:延迟、利用率、饱和度的定义,负载还是架构,问题陈述和科学方法,USE、RED、负载特征、下钻和延迟分析,排队论,以及平均值、百分位、多峰分布。这些是后面每一章都默认你知道的。扩展性模型、容量规划、可视化几节,做压测和画图时再回来查。

  1. Give a man a fish and you…约 400 词开篇作者为什么写方法论:只会读指标不够;这一章的三个部分。
  2. Terminology约 300 词术语IOPS、吞吐、响应时间、延迟等定义;延迟有两种用法。
  3. Models约 100 词模型两个简单模型的引子。
  4. System Under Test约 200 词被测系统干扰从哪来;云上看不到同一台宿主上的邻居。
  5. Queueing System约 100 词排队系统把组件看成排队系统来预测,细节在排队论一节。
  6. Concepts约 100 词概念一组概念的引子。
  7. Latency约 400 词延迟延迟量的是哪一段;为什么尽量换算成时间来比较。
  8. Time Scales约 200 词时间尺度从 CPU 周期到整机重启,各种延迟差几个数量级。
  9. Trade-Offs约 200 词权衡好、快、省只能选两样;CPU 换内存;参数的两头。
  10. Tuning Efforts约 300 词在哪一层调越靠近干活的地方调,收益越大。
  11. Level of Appropriateness约 300 词做到什么程度做多深看投入产出;高频交易和小创业公司的差别。
  12. When to Stop Analysis约 400 词什么时候停三种可以停下来的情况。
  13. Point-in-Time Recommendations约 300 词建议有时效网上搜来的参数为什么危险;参数改动最好进版本控制。
  14. Load vs. Architecture约 200 词负载还是架构排队是因为压力太大,还是因为实现本身有问题。
  15. Scalability约 400 词扩展性吞吐随负载的曲线和拐点;返回错误为什么能保住延迟。
  16. Metrics约 300 词指标常见指标类型;观测有开销,指标本身也会错。
  17. Utilization约 500 词利用率按时间和按容量两种定义;忙满不等于装满。
  18. Saturation约 100 词饱和度排不上的工作就是饱和,任何程度都值得看。
  19. Profiling约 100 词剖析定时采样得到粗粒度的画面,细节在第 6 章。
  20. Caching约 800 词缓存命中率和未命中率哪个更说明问题;冷、温、热缓存。
  21. Known-Unknowns约 200 词已知的未知知道自己不知道什么,才知道去查什么。
  22. Perspectives约 100 词视角两种分析视角的引子。
  23. Resource Analysis约 200 词资源分析从资源往上看,盯利用率和饱和度。
  24. Workload Analysis约 300 词负载分析从应用往下看,盯请求、延迟和错误。
  25. Methodology约 200 词方法方法总表;处理新问题时第一个该用的是问题陈述。
  26. Streetlight Anti-Method约 200 词路灯反方法只用熟悉的工具,找到的未必是那个问题。
  27. Random Change Anti-Method约 200 词随机改动反方法乱改参数看效果:慢,还留下没人懂的配置。
  28. Blame-Someone-Else Anti-Method约 100 词甩锅反方法没有数据就把问题推给别的团队;怎么应对。
  29. Ad Hoc Checklist Method约 300 词临时检查清单现成清单见效快,但偏向有现成修法的问题,要常更新。
  30. Problem Statement约 200 词问题陈述碰到新问题时先问的几件事。
  31. Scientific Method约 500 词科学方法问题、假设、预测、测试、分析;观测和实验两种测试。
  32. Diagnosis Cycle约 100 词诊断循环假设和数据之间来回要快。
  33. Tools Method约 200 词工具法按工具挨个查,盲区自己看不见。
  34. The USE Method约 1800 词USE 方法对每个资源查利用率、饱和度、错误:顺序、资源清单、读法、软件资源。
  35. The RED Method约 300 词RED 方法对每个服务查请求率、错误、耗时;请求率是负载还是架构的线索。
  36. Workload Characterization约 500 词负载特征用几个问题描述施加的负载;最大的收益来自去掉不必要的工作。
  37. Drill-Down Analysis约 600 词下钻分析监控、定位、分析三段;五个为什么。
  38. Latency Analysis约 300 词延迟分析把延迟一分为二,追大的那一半。
  39. Method R约 100 词方法 ROracle 数据库的方法,思路就是延迟分析,知道名字即可。
  40. Event Tracing约 300 词事件跟踪汇总丢了细节时逐个看事件:输入、时间、结果。
  41. Baseline Statistics约 400 词基线统计平时存一份全量指标,出问题时有得比。
  42. Static Performance Tuning约 200 词静态性能调优不加负载,逐个组件查配置合不合理。
  43. Cache Tuning约 200 词缓存调优缓存放得越高越好;查命中率、大小和双重缓存。
  44. Micro-Benchmarking约 300 词微基准测试简单的人造负载;最好再用别的工具核对一遍。
  45. Performance Mantras约 200 词性能箴言七句话,按效果从大到小排的优化方向。
  46. Modeling约 200 词建模建模、模拟、测量三种评估,最好做两种。
  47. Enterprise vs. Cloud约 100 词企业与云一段观点:云上可以租环境直接测,不必建模。
  48. Visual Identification约 400 词目测从测试曲线认出线性、竞争、一致性、拐点和天花板。
  49. Amdahl’s Law of Scalability约 300 词Amdahl 扩展性定律串行部分限制扩展;怎么用测试数据拟合参数。
  50. Universal Scalability Law约 200 词通用扩展性定律多一个一致性系数,能描述加并发反而变慢。
  51. Queueing Theory约 800 词排队论Little 定律、Kendall 记法;M/D/1 为什么过了六成就疼。
  52. Capacity Planning约 100 词容量规划容量规划的引子。
  53. Resource Limits约 500 词资源上限按每个请求的资源消耗外推最大吞吐。
  54. Factor Analysis约 400 词因素分析配置组合太多时,从最大配置一项项往下减。
  55. Scaling Solutions约 300 词扩展方案纵向、横向扩展,自动伸缩和分片。
  56. Statistics约 100 词统计统计一节的引子。
  57. Quantifying Performance Gains约 200 词量化收益用观测或实验估计修好能快多少。
  58. Averages约 400 词平均值几种平均值;按时间的平均和衰减平均会掩盖突发。
  59. Standard Deviation, Percentiles, Median约 100 词标准差、百分位、中位数描述分布的几个数,SLA 为什么写百分位。
  60. Coefficient of Variation约 100 词变异系数标准差除以平均值,变成一个能比较的数。
  61. Multimodal Distributions约 200 词多峰分布双峰时平均值落在谷里,谁也不代表。
  62. Outliers约 200 词离群值极少数极慢的请求,多数指标都看不出来。
  63. Monitoring约 100 词监控把指标记成时间序列,和过去比。
  64. Time-Based Patterns约 300 词时间规律按小时、天、周、季度、年的周期,和不规律的起落。
  65. Monitoring Products约 200 词监控产品监控产品的一般介绍,选型时看第 4 章更合适。
  66. Summary-Since-Boot约 100 词开机以来的汇总没有监控时,至少和开机以来的平均值比一比。
  67. Visualizations约 100 词可视化可视化的引子。
  68. Line Chart约 200 词折线图只画平均值的折线和加上百分位的折线差在哪。
  69. Scatter Plots约 200 词散点图每个事件一个点,看得见离群值;点多了糊成一片。
  70. Heat Maps约 300 词热图把散点按桶量化,量再大也看得清分布和双峰。
  71. Timeline Charts约 200 词时间线图浏览器的瀑布图;服务端看线程和 CPU 的时间线。
  72. Surface Plot约 200 词曲面图三维线框图,要成规模机房的数据,单机排查用不到。
  73. Visualization Tools约 100 词可视化工具文本工具和图形工具的泛泛比较,没有可操作的内容。
  74. Exercises约 100 词习题习题;本页的诊断题可以代替。

词与短语

只收先读和用到再查两档的节。斜体那一行是原句里连续的几个词,在电子书里搜它就能找到那一句。

§0 开篇

watching over the shoulder
… learned by watching over the shoulder of …
在旁边看着学
不是「偷看」。这类诀窍是站在老手身后看他怎么查学来的,手册里没有。

§2.3.4 Tuning Efforts

a tax has already been paid
… but a tax has already been paid …
代价已经付过了
tax 比喻开销:上层的代码已经跑过了,在存储层再怎么调,省下的只是最后一截。

§2.3.5 Level of Appropriateness

low-hanging fruit
good news: low-hanging fruit!
唾手可得的收获
低处的果子,伸手就摘到。没人做过基础分析的地方,随便一查就有收获。

§2.3.6 When to Stop Analysis

which never happens in practice
(which never happens in practice)
(实际上从来不会发生)
自嘲:公司时间里没别的事可做,这种情况根本不存在。
canary
… might be a canary for a …
预警信号
矿井里的金丝雀先出事,提醒矿工有毒气。小问题可能预示着以后的大问题。

§2.3.7 Point-in-Time Recommendations

cripple
They can also cripple performance if …
(让性能)严重受损
raiding someone else’s medicine cabinet
… akin to raiding someone else’s medicine cabinet …
翻别人家的药箱乱吃药
比喻照抄网上的调优参数:不对症、可能过期、本来只该短期用。

§2.3.8 Load vs. Architecture

make forward progress
… only one thread can make forward progress …
往前推进(干成活)
并发里的说法:线程不是在等,而是真正在完成工作。

§2.3.10 Metrics

plain wrong
… and even plain wrong (due to bugs).
干脆就是错的
plain 在这里是「彻头彻尾」,不是「朴素」。

§2.5.1 Streetlight Anti-Method

hit or miss
This approach is hit or miss …
全凭运气
碰上了就碰上,碰不上就碰不上,不是「命中或未命中」的技术含义。
an issue but not the issue
… may be an issue but not …
是一个问题,但不是那个问题
原文 an 和 the 用斜体强调:找到的毛病是真的,却不是让系统变慢的主因。

§2.5.2 Random Change Anti-Method

unearth
… may eventually unearth tuning that works …
(碰巧)挖出来
back out
… a need to back out the change.
撤回(改动)
back out 在运维里是回滚,不是「退出」。

§2.5.3 Blame-Someone-Else Anti-Method

Maybe it’s the network
“Maybe it’s the network. Can you …
没准是网络的问题吧
作者举的典型甩锅台词:没有任何数据支撑的猜测。

§2.5.4 Ad Hoc Checklist Method

canned
Stepping through a canned checklist is …
现成的、预先写好的
不是「罐头」。canned checklist 是照着走的固定清单。

§2.5.6 Scientific Method

rule out
… environment have been ruled out.
排除

§2.5.8 Tools Method

prescriptive
… is a prescriptive checklist showing which …
规定好怎么做的

§2.5.9 The USE Method

disguise
… may disguise short periods of 100% …
掩盖
more useful than it sounds
This is more useful than it sounds
比听起来有用
往轻里说:三项都正常听着像白查了,其实排除了一大块范围。
process of elimination
This is the process of elimination.
排除法

§2.5.11 Workload Characterization

throw load at
… appears to be throwing load at …
往(某处)猛砸请求
throw 在这里是一股脑地压过去,不是「扔掉」。

§2.5.12 Drill-Down Analysis

peel away layers
… peeling away layers of the software stack …
一层层剥开

§2.5.13 Latency Analysis

if you will
… binary search of latency, if you will.
不妨这么叫
不是「如果你愿意」。作者给一个说法加的保留:可以把它看成对延迟做二分查找。

§2.5.16 Baseline Statistics

better than nothing
This is coarse, but better than nothing.
聊胜于无

§2.5.20 Performance Mantras

when they’re not looking
Do it when they’re not looking.
趁用户不注意的时候(做)
they 指用户:挪到低峰时段去做,没有偷偷摸摸的意思。

§2.6.5 Queueing Theory

bounding resource
… often the bounding resource for an …
决定上限的资源
bound 是「给……划定上限」。应用快不快,常常由磁盘的延迟封顶。
wait their turn
… and must wait their turn.
排队等着轮到自己
the best case
… it shows the best case.
最乐观的情况
不是「最好的例子」。M/D/1 假设服务时间完全固定,所以算出来的等待是下限。

§2.7.2 Factor Analysis

get out of hand
… this can quickly get out of hand …
(数量)失控

§2.8.2 Averages

mask
… which masked periods in which CPU …
遮住,掩盖

§2.8.5 Multimodal Distributions

almost the opposite
… in fact, it is almost the opposite.
几乎正相反
平均值本该代表数据的集中位置,在双峰分布里它落在数据最少的地方。

§2.10.2 Scatter Plots

wall of paint
… become a “wall of paint.”
糊成一面墙
点太多叠在一起,只剩一片颜色,什么也看不出来。

诊断题:换成你来查

场景和输出都是本站编的。先自己判断,再点选项看解释。

这组数说明是负载问题,还是服务自身的问题?§2.5.10

场景:你的 C++ 推送网关,周二下午开始有用户抱怨慢。你从接入层的指标里拉了三个时段:

time      req/s   err/s   p50   p99
Mon 15h    4200       2   3ms   18ms
Tue 15h    4150       3   4ms   95ms
Tue 16h    4180       2   4ms  110ms

RED 里的请求率是「负载还是架构」的第一条线索:请求率持平、耗时上升,指向服务自身(代码、配置、依赖、它用的资源),加机器解决的是负载问题。p50 只涨了一点、p99 涨了五六倍,说明一部分请求走上了慢路径:用问题陈述问「最近改了什么」,同时把慢请求的时间拆开。错误数正常只说明没失败,不说明不慢;没有数据就推给网络组,就是书里的甩锅反方法。

流量涨三分之一,平均延迟会变成多少?§2.6.5

场景:ARM 板上一个单线程的日志压缩线程,每条日志固定耗时约 2 ms,现在每秒来 300 条,利用率 60%,每条从进队列到写完平均 3.5 ms。下个版本日志量要涨到每秒 400 条。按 M/D/1 估,每条平均要多久?

M/D/1 的平均响应是 S(2 − ρ) / (2(1 − ρ)):ρ = 0.6 时 2 × 1.4 / 0.8 = 3.5 ms,ρ = 0.8 时 2 × 1.2 / 0.4 = 6 ms。流量涨 33%,延迟涨 71%,这就是排队带来的非线性。80% 没到 100%,队列是稳定的,只是等得更久;超过 100% 才会无限增长。而且固定服务时间是最好的情况:每条耗时有波动的话(实际总有),按 M/M/1 是 5 ms 涨到 10 ms。下一步要么把单条压缩变快(降低 S),要么拆成两个线程。

平均延迟在 SLA 以内,这组数该怎么读?§2.8.5

场景:一个带本地 LRU 缓存的配置查询服务,监控显示平均延迟 3.2 ms,SLA 写的是平均不超过 5 ms,一切「正常」。你把一分钟的请求按延迟分了桶:

latency    count
0-1ms       6400
1-4ms        150
4-8ms       1900
8-16ms      1500

平均值、标准差、百分位都默认分布只有一个峰。这里的平均值没有算错,只是落在两个峰之间,几乎没有请求真的花了 3.2 ms;中位数也只说出了快的那一峰。下一步看缓存的命中率和每秒未命中次数(§2.3.14),再对未命中那条路径做延迟分析。SLA 最好改用 p99 这类百分位,再配上直方图。

监控说 CPU 从没过半,为什么还会超时?§2.8.2

场景:8 核服务器上的 C++ 撮合服务,监控是 5 分钟粒度,CPU 从没超过 50%,但每隔几分钟就有一批请求超时。你在超时前后跑了 vmstat 1:

 r   us  sy  id
 3   38   4  58
19   93   6   1
22   94   5   1
 2   35   4  61

利用率总是某个时间段的平均,5 分钟的 50% 里可以藏着好几秒的 100%。vmstat 的 r 是可运行的线程数(在跑的加在等的,§6.6.2),19、22 远大于 8 核,就是 CPU 饱和;等磁盘的线程算在 b 列,不在 r。下一步在突发时用 pidstat 1 或 perf 抓是谁(定时任务、批处理、日志压缩),监控改用秒级间隔,或者直接监控饱和度,比如 PSI 的 cpu 一行。

换一个快 10 倍的库,请求能快多少?§2.8.1

场景:一个请求平均 12 ms。剖析显示其中 3 ms 花在 JSON 序列化上。同事提议换一个号称快 10 倍的序列化库,说「这样请求就能快 10 倍」。

用时间来量化:新耗时 = 12 − 3 + 0.3 = 9.3 ms。收益的上限由被优化部分的占比决定,这和 Amdahl 定律是同一个道理(§2.6.3)。还要确认这 3 ms 是同步地花在请求路径上的:书里提醒,异步做的部分(比如后台刷盘)省下来也不影响请求延迟。剩下的 9 ms 在哪,接着按延迟分析拆。

值得停下来的句子

For every resource, check utilization, saturation, and errors.— §2.5.9。本站译:对每一个资源,查它的利用率、饱和度和错误。

整个 USE 方法就这一句,重点在「每一个」。它从资源清单出发,而不是从手边的工具出发,所以没有工具能回答的问题也会留在清单上,你会知道自己哪里还没看。对 C++ 服务来说,清单上还应该有线程池、锁、连接池、文件描述符上限和容器的 cgroup 限额:这些地方的饱和,CPU 和磁盘的指标看不出来。

Every time you see an average used as a performance metric, especially an average latency, ask: What is the distribution?— §2.8.5。本站译:每次看到用平均值当性能指标,尤其是平均延迟,都要问一句:它的分布是什么样的?

监控大盘、压测报告、SLA 最爱写平均值,因为它只有一个数。问分布的具体做法是:要直方图或热图,至少要 p50、p99 和最大值;看是不是有两个峰、有没有零星的极端值。很多「平均正常、用户却在骂」的问题,答案都在这一问里。

带走的几条

一句话:先问清楚、分清负载还是服务、把资源扫一遍,再沿着延迟往下拆;读数时记住排队和分布。

先问再敲命令

把「慢」换成一个数:哪类请求、p99 还是平均、从多少到多少;再问最近改了什么。很多问题到这里就有了方向。

§2.5.5
请求率是第一条线索

请求率平稳、耗时上升:查服务自身。两个一起涨:先当负载问题,看谁在压。

§2.5.10
USE:错误、饱和、利用率

对每个资源按这个顺序查,软件资源(锁、线程池、fd、限额)也算。查不到的指标记下来,那是已知的未知。

§2.5.9
六成就开始疼

服务时间固定时,利用率 60% 平均响应是服务时间的 1.75 倍,80% 是 3 倍;服务时间随机时等待再翻一倍。

§2.6.5
看到平均就问分布

双峰时平均值落在谷里;短时突发会被长间隔的平均摊平。要直方图、p99 和秒级数据。

§2.8.5
收益用时间算

12 ms 的请求里能省 3 ms,最多快 1.3 倍。先算上限再动手,挑占比最大的那段。

§2.8.1
一次只改一处

先写预测再改;没效果就改回去再试下一个,别让说不清来由的配置留在生产上。

§2.5.6