第 1 級 · 有問題的發佈
09:10 發佈了一個新構建。這個月已經很艱難:錯誤預算只剩 20 %。部署幾分鐘後,燃燒速率告警響了。保護好預算。
- 結束時剩餘錯誤預算 ≥ 18.5 %
- 部署後平均錯誤率 ≤ 0.65 %
- 集羣成本 ≤ $9.50
你是一項 Web 服務的值班工程師:負載均衡器後面是一組實例,緩存放在數據庫前面,可用性目標是 99.9 %。模型每分鐘用教科書公式計算排隊延遲、超時、緩存命中和數據庫負載,以及你的決策要花多少錢。
實例集羣的下限。調高會立即啓動實例,但它們仍要等啓動延遲過去才能提供服務。
按使用率目標跟蹤;實例還在啓動時不會再次擴容。關閉 = 恰好保持最小實例數。
越低 = 餘量越大,成本也越高。測得的使用率不會超過 100 %,所以已飽和的集羣只能一步一步增長。
TTL 越長 = 命中越多,但返回的答案可能越舊(平均時齡 ≈ TTL/2)。
加載熱點鍵 6 分鐘(每分鐘填充緩存的 12 %),代價是每秒額外 600 次數據庫查詢。
佔 30 % 的低優先級流量(預取、批處理、爬蟲)中,在負載均衡器處以“請稍後重試”拒絕的比例。
這個重量級功能讓每個請求多耗 20 ms CPU,並多一次數據庫查詢。關閉 = 優雅降級。
在一組全新的實例上重新部署上一個良好版本(5 分鐘,收費兩次),然後切換流量。再按一次會重新開始準備;如果線上沒有有問題的版本,這樣做只會白白花錢。
| 燃燒速率(1 小時) | 0.0 × |
|---|---|
| 請求數 | 1125 req/s |
| 提供服務的實例 | 10 |
| 正在啓動的實例 | 0 |
| 緩存命中率 | 77 % |
| 數據庫使用率 | 19 % |
| 被丟棄的流量 | 0 % |
| 集羣成本 | 4.00 $/h |
| 迄今成本 | 0.00 $ |
| 緩存答案的平均時齡 | 30 s |
| 問題版本上的流量 | 0 % |
| 推薦功能可用 | 100 % |
09:10 發佈了一個新構建。這個月已經很艱難:錯誤預算只剩 20 %。部署幾分鐘後,燃燒速率告警響了。保護好預算。
一個指向該服務的連結正在迅速傳開,預計今早某個時候會出現流量激增——沒人知道是何時,也不知道會有多大。目前新實例需要 8 分鐘才能啓動。流量來臨時,要讓錯誤率和延遲保持低水平,同時不要為閒置的容量浪費金錢。
中午高峯時,一個維護腳本清空了整個緩存。現在每個請求都落到數據庫上,而數據庫是按平時 85 % 的命中率設計的。要讓服務恢復,又不能壓垮數據庫。
模擬器使用的每一個關係式及其來源。標示為假設的常數是示意校準值。
λ(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 服務的示意值。N = instances × 16 workers, a = λ·S; C(a, N) = B / (1 − (a/N)(1 − B)), B = Erlang B[3][6]P(W > t) = C·e^(−(N/S − λ)·t); timeouts = P(W > 2 s); a ≥ N ⇒ failed share = 1 − N/a[3]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]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 服務的示意值。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)。種子會顯示出來,並可分享。
教育模型,不可用於實際營運決策。真實場地會按自己的設備及數據校準每一個常數。