IT 运维:站点可靠性 实时模型

你是一项 Web 服务的值班工程师:负载均衡器后面是一组实例,缓存放在数据库前面,可用性目标是 99.9 %。模型每分钟用教科书公式计算排队延迟、超时、缓存命中和数据库负载,以及你的决策要花多少钱。

你将学到什么

模拟器

时间 0 min
请求数 1125 · 错误率 0.00% · p99 延迟 342 ms · 提供服务的实例 10 (+0) · 缓存命中率 77% · 数据库利用率 19% · 剩余错误预算(30 天) 50.0%⇉1125 请求/秒▶▶▶▶▶▶▶▶▶▶······························▶ 10 · ⚙ 0 · 52% · p99 342 ms集群利用率 52%缓存命中率 77%数据库利用率 19%⚠ 0.00% · 🔥 0.0×50%$ 4.00/h · Σ $0.00
  • 正在提供服务的实例
  • 正在启动的实例
  • 运行问题构建的实例
  • 空闲位置
  • 传入请求

控制

实例集群的下限。调高会立即启动实例,但它们仍要等启动延迟过去才能提供服务。

按利用率目标跟踪;实例还在启动时不会再次扩容。关闭 = 恰好保持最小实例数。

越低 = 余量越大,成本也越高。测得的利用率不会超过 100 %,所以已饱和的集群只能一步一步增长。

TTL 越长 = 命中越多,但返回的答案可能越旧(平均时龄 ≈ TTL/2)。

加载热点键 6 分钟(每分钟填充缓存的 12 %),代价是每秒额外 600 次数据库查询。

占 30 % 的低优先级流量(预取、批处理、爬虫)中,在负载均衡器处以“请稍后重试”拒绝的比例。

这个重量级功能让每个请求多耗 20 ms CPU,并多一次数据库查询。关闭 = 优雅降级。

在一组全新的实例上重新部署上一个良好版本(5 分钟,计费两次),然后切换流量。再次按下会重新开始准备;如果线上没有有问题的版本,这样做只会花钱。

指标

错误率
0.00%
正常
p99 延迟
342ms
正常
剩余错误预算(30 天)
50.0%
正常
集群利用率
52%
正常
燃烧速率(1 小时)0.0 ×
请求数1125 req/s
提供服务的实例10
正在启动的实例0
缓存命中率77 %
数据库利用率19 %
被丢弃的流量0 %
集群成本4.00 $/h
迄今成本0.00 $
缓存答案的平均时龄30 s
问题版本上的流量0 %
推荐功能可用100 %

趋势

错误率: — %20.000.00

危机场景

第 1 级 · 有问题的发布

09:10 发布了一个新构建。这个月已经很艰难:错误预算只剩 20 %。部署几分钟后,燃烧速率告警响了。保护好预算。

  • 结束时剩余错误预算 ≥ 18.5 %
  • 部署后平均错误率 ≤ 0.65 %
  • 集群成本 ≤ $9.50

第 2 级 · 突发人潮

一个指向该服务的链接正在迅速传开,预计今早某个时候会出现流量激增——没人知道是何时,也不知道会有多大。目前新实例需要 8 分钟才能启动。流量来临时,要让错误率和延迟保持低水平,同时不要为闲置的容量浪费金钱。

  • 平均错误率 ≤ 0.2 %
  • 平均 p99 延迟 ≤ 400 ms
  • 平均丢弃流量 ≤ 5 %
  • 总成本 ≤ $21
  • 推荐功能可用时间 ≥ 85 %

第 3 级 · 冷缓存

中午高峰时,一个维护脚本清空了整个缓存。现在每个请求都落到数据库上,而数据库是按平时 85 % 的命中率设计的。要让服务恢复,又不能压垮数据库。

  • 平均错误率 ≤ 1.5 %
  • 第一分钟之后数据库利用率始终不高于 90 %
  • 缓存答案平均时龄 ≤ 90 秒
  • 总成本 ≤ $9
  • 推荐功能可用时间 ≥ 80 %
  • 平均丢弃流量 ≤ 5 %

依据:数字背后的模型

模拟器使用的每一个关系式及其来源。标注为假设的常数是示意性校准值。

请求遵循日流量曲线加上扰动;每分钟的数量是随机的(泊松分布,正态近似),并带有少量突发性。
λ(t) = base × (1 + 0.25·sin(2π(t + clock − 6 h)/24 h)) × surge(t), clock = time of day at the start (peak at 12:00); count/min ≈ N(60λ, √(60λ)) × (1 + N(0, 0.02))[6]假设:工作进程数、服务时间、数据库容量、缓存大小、回填速度、价格以及问题版本的错误率,均为中型 Web 服务的示意值。
Erlang C:在 M/M/N 系统中,请求必须等待空闲工作进程的概率。
N = instances × 16 workers, a = λ·S; C(a, N) = B / (1 − (a/N)(1 − B)), B = Erlang B[3][6]
等待时间的尾部:等待超过 t 的概率呈指数下降;等到 2 秒超时仍未得到服务的请求会失败。超出容量的部分直接失败。
P(W > t) = C·e^(−(N/S − λ)·t); timeouts = P(W > 2 s); a ≥ N ⇒ failed share = 1 − N/a[3]
由服务时间和等待时间分位数得出的 p99 延迟。
p99 ≈ S·ln 100 + ln(C/0.01)/(N/S − λ) (service + waiting quantile, an approximation)[3][6]近似:把服务时间分位数和等待时间分位数相加,并不是二者之和的精确 p99(可能略高或略低);由于请求只需几毫秒,每一分钟内把队列视为稳态。
利特尔法则:忙碌的工作进程数 = 到达率 × 服务时间。
busy workers L = λ·S ⇒ utilization = λ·S / N[4]
TTL 缓存:请求随机到达时,每次未命中会开启一个 TTL 周期,周期内的请求都会命中。
hit = warm × rT/(1 + rT), r = λ / 20,000 objects; mean age of a cached answer ≈ T/2[5]
缓存未命中会给数据库增加负载;它的排队延迟会拖慢每个访问它的请求,也会占满应用工作进程。
DB load = λ·q·(1 − hit); query time = 5 ms/(1 − ρ_db) (≤ 250 ms); S = S_app + (1 − hit)·q·query time[6]假设:工作进程数、服务时间、数据库容量、缓存大小、回填速度、价格以及问题版本的错误率,均为中型 Web 服务的示意值。
SLO 与错误预算:燃烧速率表示预算的消耗速度是允许速度的多少倍。
budget = 1 − SLO = 0.1 %; burn = error rate / 0.1 %; Δbudget per min = burn / 43,200; burn (1 h) = mean error rate over the last 60 min / 0.1 % (window pre-filled with the opening minute)[1][2]
带启动延迟和冷却时间的目标跟踪自动扩缩容器。
desired = ⌈serving × utilization / target⌉ (utilization saturates at 100 %); new instances serve after the boot delay[6]假设:工作进程数、服务时间、数据库容量、缓存大小、回填速度、价格以及问题版本的错误率,均为中型 Web 服务的示意值。
模型使用的其他运行常数。
16 workers/instance · app time 50 ms (+20 ms and +1 query with the feature on) · 2 queries/request · DB 4,000 queries/s · 20,000 hot objects · cache refill τ = 30 min (slower while the DB is saturated) · warm-up job +12 %/min for 6 min, +600 queries/s · timeout 2 s · 30 % low-priority traffic · bad build +5 % errors, ×1.25 CPU · rollback 5 min · $0.40 per instance-hour · scale-in by ≤ 20 % of the fleet after 10 quiet minutes · up to 40 instances假设:工作进程数、服务时间、数据库容量、缓存大小、回填速度、价格以及问题版本的错误率,均为中型 Web 服务的示意值。

随机性:带种子的 mulberry32 生成器;所用分布包括均匀分布、指数分布(逆 CDF)、正态分布(Box–Muller)和泊松分布(Knuth)。种子会显示出来,并且可以分享。

来源

  1. Site Reliability Engineering — Ch. 3 Embracing Risk (error budgets), Ch. 4 Service Level Objectives — Beyer, Jones, Petoff, Murphy (eds.), O'Reilly, 2016
  2. The Site Reliability Workbook — Ch. 5 Alerting on SLOs (burn rate; 14.4× over 1 h = 2 % of a 30-day budget) — Beyer, Murphy, Rensin, Kawahara, Thorne (eds.), O'Reilly, 2018
  3. Teletraffic Engineering Handbook — Erlang C formula; waiting-time distribution for M/M/n, FCFS — ITU-D Study Group 2 Question 16/2 (V. B. Iversen), 2005
  4. J. D. C. Little — A Proof for the Queuing Formula: L = λW — Operations Research 9(3):383–387, 1961
  5. J. Jung, A. W. Berger, H. Balakrishnan — Modeling TTL-based Internet Caches — IEEE INFOCOM 2003, 2003
  6. M. Harchol-Balter — Performance Modeling and Design of Computer Systems: Queueing Theory in Action (M/M/k, server farms, capacity provisioning) — Cambridge University Press, 2013

谁在从事这份工作

教育模型,不可用于实际运营决策。真实站点会根据自己的设备和数据校准每一个常数。