WALL · 一本排队与拥塞的小书

你的服务器还有 20% 的富余,用户已经在骂了。你的第一反应大概是加机器、优化代码、换更快的数据库——这三件事都在打同一个靶子:速度。而这本书想说的是,你打错靶了。

慢不是速度问题,是余量问题。等待时间 = 满的程度 × 不齐的程度 × 一次要多久,三个因子里只有一个是速度,而且是唯一线性的那个。

6 卷 24 章 24 个真 demo 零依赖 · 全 SVG 本机真机实测 10200 位顾客
0 3 6 9 等待 100% 那面墙 不齐一倍 → 曲线抬高 我最多能忍 3 个服务时长 天花板 75% 这 25% 不是浪费 是你买的响应时间 你以为你在这儿 利用率 ρ ── 你把这台机器用得多满

这本书的招牌

五个系统,吞吐完全相同、平均服务时间完全相同、因此利用率完全相同(都是 80%)。按任何一个标准监控指标看,它们是同一个系统。唯一的区别是「整齐程度」:

走法       到达    服务     平均等待     天花板(我最多能忍 2 个服务时长)
─────────────────────────────────────────────────────────────
D/D/1      ca²=0   cs²=0     0.0000        100.0%     ← 一个人都没等过
D/M/1      ca²=0   cs²=1     1.6927         80.0%
M/D/1      ca²=1   cs²=0     2.0000         80.0%
M/M/1      ca²=1   cs²=1     4.0000         66.7%     ← 教科书默认款
M/H₂/1     ca²=1   cs²=10   22.0000         26.7%     ← 你的系统大概在这儿

机器没换、活没多、速度没变,平均等待从 0 走到 22 个服务时长。最后一列更狠:同样的容忍度,第一行能把机器跑到 100%,最后一行只能跑到 26.7%——七成多的产能必须空着

而这个区间,在你的监控面板上是完全不可见的。

不是模拟:我在这台电脑上真的排了一遍队

排队论没有标准库可以对照(不像压缩之于 zlib)。所以这本书的对照对象是机器本身:真的 CPU busy loop 当服务、真的时刻表当到达、真的单线程服务台,烧掉 27 秒排出 10200 位顾客

队               n      真机量到     Lindley 预测    纸上公式
─────────────────────────────────────────────────────────────
D/D/1 ρ=0.8    800      0.001ms       0.000ms      0.000ms
M/D/1 ρ=0.8   1400      4.263ms       4.256ms      4.000ms
M/M/1 ρ=0.8   3000      6.686ms       6.680ms      8.000ms
M/M/1 ρ=0.5   1000      1.753ms       1.751ms      2.000ms
M/M/1 ρ=0.7   1400      3.845ms       3.843ms      4.667ms
M/M/1 ρ=0.9   2600     18.524ms      18.507ms     18.000ms

★ 把真机**真的烧掉**的服务时长喂回 Lindley 递推,逐个顾客比对开始时刻:
  10200 位顾客,中位误差是**个位数微秒**。

第一行是最想让你看见的一行:同一台机器、同样忙到 80%、同样的吞吐,只要来得准走得准,800 个请求里没有一个等过哪怕一毫秒。

卷 I

排起来

QUEUE

队不是从「机器不够快」来的。它有两个成因,而速度只是其中半个。

卷 II

不齐

JITTER

第二个成因。它没有名字,所以你一直没在账单上看见它。

卷 III

那面墙

WALL

一条你没见过的曲线,和它在 100% 处的那道竖线。

卷 IV

加人

SCALE

加机器有用,但用处和你以为的完全不是一回事。

卷 V

插队

ORDER

总时间是定死的。调度只决定这笔账由谁付。

卷 VI

留余

SLACK

你买的从来不是速度,是余量。

写给谁

  • 看过 p99 曲线,但说不清它为什么长那样的人;
  • 被问过「服务器利用率才 40%,是不是太浪费了」而答不上来的人;
  • 做过容量规划,但心里知道那个「乘以 1.5」的系数是拍脑袋来的人;
  • 以及每一个排过队、堵过车、觉得「隔壁那条队总是更快」的人。

不打算做的事

  • 不教你怎么优化代码。这本书从头到尾在说,那是三个因子里效果最小的一个。
  • 不推荐任何具体的技术选型。这里的东西对所有语言、所有框架一样成立。
  • 不假装公式很准。每一个近似都会标出它在哪里失灵、偏多少(第 8 章有一整张表)。

怎么读这本书

  • 按顺序读。后面每一章都在用前面的结论,尤其是第 2、8、9 章那三个地基。
  • 每章开头那个「▷ 先估一个数」,真的先估一个。整本书都在治「线性直觉在非线性世界里偏得多离谱」这个毛病,而唯一有效的疗法是让你亲眼看见自己偏了几倍。
  • 时间紧的话,最短路径是:第 1 章(那张对照表)→ 第 8 章(三个因子)→ 第 9 章(那面墙)→ 第 12 章(招牌)→ 第 24 章(自查表)。五章,一小时,够你回去改三个配置。
  • 所有 demo 都可以拖。数字全是引擎当场算的,不是写死的图片。