跳轉到

第一部分:告警系統設計

< 返回目錄 | 下一題:批次處理策略 >


場景:凌晨三點,你被告警叫醒

手機震動,PagerDuty1 顯示:「API 請求失敗」。你睡眼惺忪地看著螢幕,腦中閃過第一個念頭:

「又來了?」

這已經是本週第五次被單次失敗叫醒。每次查完都發現系統正常——只是偶發的單次失敗。

你決定:受夠了這種無效告警,要重新設計一個真正有用的告警系統。

你開始思考問題的根源:現在的告警是「事件驅動」的——每發生一次失敗就觸發。但這個觀察維度根本沒有判斷力,因為正常系統本來就會偶爾失敗。

你需要換一個觀察維度:不看「這一次失敗了沒」,而是看「這段時間內,失敗的次數是否異常」。這就把問題從「單一事件的是非題」變成「時間窗口內的統計量」。

但問題來了:什麼叫「異常」?要回答這個,你得先知道「正常」長什麼樣——正常系統在一段時間內,預期會失敗幾次?波動範圍多大?超過多少才算不正常?這些問題,需要建立「正常狀態的數學模型」來回答。


第 1 題:從「一次失敗」到「完整告警系統」

這道題將帶你從「一個請求失敗了」這個簡單觀察出發,逐步建立完整的數學工具箱。每個小題解決一個具體問題,最後你會發現:這些工具有一個共同的名字。


(a) 單次請求的判斷力

3 分大二

監控系統剛收到一個請求失敗的通知。同事緊張地問:「系統是不是掛了?」

你需要知道:正常系統下,單次請求失敗的機率是多少?

題目

  1. 定義隨機變數 \(X\) 表示單次請求結果(成功 = 1,失敗 = 0)。若系統正常時成功率 \(p = 0.95\),寫出 \(P(X=0)\)\(P(X=1)\)

  2. 從定義出發,計算 \(E[X]\)(不可直接套公式)

解答
  1. \[P(X = 1) = 0.95, \quad P(X = 0) = 0.05\]

    這可以統一寫成:\(P(X = x) = p^x (1-p)^{1-x}\),其中 \(x \in \{0, 1\}\)

  2. \[E[X] = \sum_{x \in \{0,1\}} x \cdot P(X=x) = 0 \times 0.05 + 1 \times 0.95 = 0.95\]

    為什麼這樣算就是「期望值」?

    這個公式其實是「加權平均」:每個可能的值 \(x\),乘以它出現的機率 \(P(X=x)\),再加總。機率越大的值,對平均的貢獻越大。

    直覺上,如果你做 1000 次實驗:大約 950 次得到 1,50 次得到 0。全部加起來除以 1000:

    \[\frac{950 \times 1 + 50 \times 0}{1000} = \frac{950}{1000} = 0.95\]

    這正是 \(E[X]\) 的值。所以期望值代表「長期下來的平均結果」。

這個計算有什麼用?

回答你的問題:光看一次失敗,判斷不了系統是否異常。因為 \(P(X=0) = 0.05\),正常系統平均每 20 次請求就會失敗一次——這是「底噪」,不是故障。

建立基準線\(E[X] = 0.95\) 代表「長期下來,平均每 100 次請求有 95 次成功」。這是你告警系統的基準線

週期 請求數 \(n\) 預期失敗 = \(n \times 0.05\)
10 秒 2,000 100 次
1 分鐘 12,000 600 次
5 分鐘 60,000 3,000 次

(b) 正常波動的範圍

3 分大二

好,你知道正常失敗率是 5% 了。那直接設「超過 5% 就告警」不行嗎?

問題是:5%(期望值)是「中線」,不是「上界」

你盯著 dashboard 看了幾天,發現每分鐘的失敗次數都不一樣:612、589、623、571、608... 系統都正常,但數字在 600 上下跳動。這是因為每次請求成功或失敗本身就有隨機性,觀測值天生會波動。

期望值是這個波動的「中心點」——大約 50% 的正常觀測會在期望值以上,50% 在以下。如果用期望值當閾值,你會有一半的時間在告警,但系統根本沒壞。

所以問題變成:正常波動的「邊界」在哪裡? 超過多少才算「真的不正常」而不是「運氣差一點」?

你需要知道:正常波動的範圍有多大?

要回答這個,你需要知道變異數——它量化「波動幅度」。有了它,你才能設一個合理的閾值:高於正常波動範圍才告警。

題目:從定義出發,計算 \(\text{Var}(X)\)

解答
\[\text{Var}(X) = E[X^2] - (E[X])^2\]

\(X^2\) 是什麼?它是一個新的隨機變數,定義為「對 \(X\) 的每個取值平方」。由於這裡 \(X \in \{0, 1\}\),而 \(0^2 = 0\)\(1^2 = 1\),所以 \(X^2 = X\),於是:

\[E[X^2] = E[X] = 0.95\]
\[\text{Var}(X) = 0.95 - 0.95^2 = 0.95 \times 0.05 = 0.0475\]

為什麼這樣算就是「波動幅度」?

變異數的原始定義是 \(\text{Var}(X) = E[(X - \mu)^2]\),也就是「每次結果離平均值的偏差,取平方,再算期望」。

為什麼要平方?因為偏差有正有負(有時高於平均,有時低於平均),直接加總會互相抵消。平方後全變正數,就能累積起來。

從原始定義到計算公式

\[E[(X - \mu)^2] = E[X^2 - 2\mu X + \mu^2]\]

期望值的線性性質(常數可以提出來、加法可以拆開):

\[= E[X^2] - 2\mu E[X] + \mu^2 = E[X^2] - 2\mu^2 + \mu^2 = E[X^2] - \mu^2\]

因為 \(\mu = E[X]\),所以 \(\text{Var}(X) = E[X^2] - (E[X])^2\)

直覺驗證:如果做 1000 次實驗:

  • 950 次得到 1,偏差 = \(1 - 0.95 = 0.05\),平方 = \(0.0025\)
  • 50 次得到 0,偏差 = \(0 - 0.95 = -0.95\),平方 = \(0.9025\)

加權平均:\(0.95 \times 0.0025 + 0.05 \times 0.9025 = 0.0475\)

這就是變異數。它代表「平均來說,結果離期望值有多遠(的平方)」。

這個計算有什麼用?

設計告警 buffer:假設觀察 \(n\) 次請求,失敗次數 \(F = \sum_{i=1}^{n} (1 - X_i)\)。由於獨立性:

\[\text{Var}(F) = n \cdot \text{Var}(1-X) = n \cdot \text{Var}(X) = n \times 0.0475\]

標準差 \(\sigma_F = \sqrt{n \times 0.0475}\)

告警邏輯if 失敗次數 > 預期 + k × 標準差 → 告警

例如 \(n = 12000\)(1 分鐘),\(\sigma_F = \sqrt{12000 \times 0.0475} \approx 23.9\)

\(k = 3\),則「失敗次數 > 600 + 72 = 672」才告警。

數學小結:你剛才發現了 Bernoulli 分布

你定義的 \(X\)——只有 0 和 1 兩個值、機率分別為 \(1-p\)\(p\)——數學上叫做 Bernoulli 分布,記作 \(X \sim \text{Bernoulli}(p)\)

性質 公式
PMF \(P(X=x) = p^x(1-p)^{1-x}\)\(x \in \{0,1\}\)
期望值 \(E[X] = p\)
變異數 \(\text{Var}(X) = p(1-p)\)

© 告警閾值設計

4 分大三

現在你有兩個數字:期望值和變異數。但設閾值時有個小問題:

  • 期望值:正常情況下失敗次數的「中線」,單位是「次」
  • 變異數:正常波動的「幅度」,但單位是「次²」

如果要設「期望 + 波動範圍」當閾值,你不能把「次」和「次²」直接相加——單位不對。

解法很簡單:開根號

\[\sigma = \sqrt{\text{Var}(X)}\]

這個 \(\sigma\)標準差(standard deviation),單位跟原數據一樣,可以直接跟期望值相加減。

標準差就是「開過根號的變異數」,讓單位一致、方便做加減運算。

現在可以設閾值了。直覺的做法是:中線往上推幾倍波動幅度,就是「正常範圍的邊界」

\[\text{閾值} = \text{期望} + k \times \text{標準差}\]

這裡的 \(k\) 代表「容忍幾倍波動」。但為什麼需要 \(k\)?直覺上 1 倍波動不就是「正常範圍」了嗎?

問題是:1 倍標準差只能覆蓋「大部分」正常情況,不是「幾乎全部」\(k\) 越大,覆蓋的正常情況越多,誤報越少——但也越可能漏掉真正的故障。

\(k\) 是一個業務決策,取決於你對誤報的容忍度:

  • 告警很重要、寧可誤報不可漏報 → \(k\) 小一點
  • 告警成本高、不想半夜被吵醒 → \(k\) 大一點

但問題來了:給定一個 \(k\),誤報率「具體」是多少?

  • \(k\) 太小 → 正常波動也會觸發(誤報
  • \(k\) 太大 → 真正故障也不告警(漏報

你需要知道:給定 \(k\),誤報率是多少?

如果你能算出這個,選 \(k\) 就有數學依據了。比如:「我每個月最多能接受被誤報叫醒 3 次,對應的誤報率是多少?\(k\) 應該設多少?」

要精確回答這個問題,光知道期望和標準差還不夠——你得知道「\(n\) 次請求中失敗幾次」的完整分布,才能算出「超過閾值的機率」。

這裡有一個建模上的轉換:前面我們一直在講「週期」(1 分鐘、10 秒),但數學上我們用「\(n\) 次請求」來表達。週期只是決定了 \(n\) 的大小:

週期 請求次數 \(n\)
10 秒 2,000(200 次/秒 × 10 秒)
1 分鐘 12,000
5 分鐘 60,000

這樣我們就把時間維度抽象掉,專注於一個更簡單的問題:「\(n\) 次請求中,成功幾次?」


(c-1) 推導成功次數的機率公式

\(S_n\) =「\(n\) 次獨立請求中,成功的次數」。推導 \(P(S_n = k)\) 的公式(\(k\) 次成功的機率)。

提示

\(S_n = k\) 表示「\(n\) 次中恰好 \(k\) 次成功」。有多少種選法?每種選法的機率是多少?

解答

思考過程

  1. 先想一種「特定排列」,比如「前 k 次都成功,後 n-k 次都失敗」
  2. 這種特定排列的機率 = \(p^k \times (1-p)^{n-k}\)
  3. 但「恰好 k 次成功」不只這一種排列,成功可以落在任意位置
  4. 從 n 個位置選 k 個當成功,有 \(\binom{n}{k}\) 種選法
  5. 每種選法機率一樣,所以總機率 = 選法數 × 單一排列機率

結論

\[P(S_n = k) = \binom{n}{k} p^k (1-p)^{n-k}, \quad k = 0, 1, \ldots, n\]

(c-2) 從單次統計量到週期統計量

前面 (b) 題建立了告警的概念:「期望 + k 倍標準差」。但那是針對單次請求 \(X\) 的。

實際監控時,你不會看「這一次請求成功沒」,而是看「這一分鐘內失敗了幾次」。所以要把告警公式應用到 \(S_n\)(n 次請求的成功總數)上:

\[\text{閾值} = E[S_n] + k \times \sigma(S_n)\]

問題是:\(E[S_n]\)\(\text{Var}(S_n)\) 怎麼從 \(E[X]\)\(\text{Var}(X)\) 算出來?

題目:證明 \(E[S_n] = n \cdot E[X]\)\(\text{Var}(S_n) = n \cdot \text{Var}(X)\)

解答

期望值

  1. \(S_n = X_1 + X_2 + \cdots + X_n\)(定義)
  2. \(E[S_n] = E[X_1 + X_2 + \cdots + X_n]\)
  3. \(= E[X_1] + E[X_2] + \cdots + E[X_n]\)(期望值的線性性質:和的期望 = 期望的和)
  4. \(= n \cdot E[X]\)(每個 \(X_i\) 期望都一樣)
  5. \(= n \cdot p\)

為什麼 \(E[X] = p\)

這是 Bernoulli 分布的特性。因為我們用 0 表示失敗、1 表示成功:

\[E[X] = 0 \times (1-p) + 1 \times p = p\]

「失敗」的貢獻是 0(0 乘以任何東西都是 0),「成功」的貢獻剛好就是它的機率 p。這不是數學巧合,而是 0/1 編碼的結果。

變異數

  1. \(\text{Var}(S_n) = \text{Var}(X_1 + X_2 + \cdots + X_n)\)
  2. \(= \text{Var}(X_1) + \text{Var}(X_2) + \cdots + \text{Var}(X_n)\)獨立時,和的變異數 = 變異數的和)
  3. \(= n \cdot \text{Var}(X)\)
  4. \(= n \cdot p(1-p)\)

為什麼 \(\text{Var}(X) = p(1-p)\)

同樣從 Bernoulli 的 0/1 結構推導。(b) 題算過:\(\text{Var}(X) = E[X^2] - (E[X])^2 = p - p^2 = p(1-p)\)

對接前面的週期概念

\(E[S_n] = n \times E[X]\),就是「單次請求的成功率 × 週期內的請求數 = 週期內的成功次數期望」。

週期 \(n\) \(E[S_n] = n \times 0.95\)
10 秒 2,000 1,900 次成功
1 分鐘 12,000 11,400 次成功

這樣就把「週期」和「成功次數分布」連接起來了。


(c-3) 計算誤報率,評估方案可行性

假設你打算用「期望 − 2 倍標準差」當閾值(成功次數太低就告警)。

\(n = 100\)\(p = 0.95\)\(k = 2\)

  1. 計算 \(E[S_n]\)\(\sigma(S_n)\)
  2. 算出閾值
  3. 計算誤報率 \(P(S_n \leq \text{閾值})\)
  4. 如果監控系統每分鐘檢查一次,這個誤報率在業務上可接受嗎?
解答

1. 計算期望和標準差

  • \(E[S_n] = n \times p = 100 \times 0.95 = 95\)
  • \(\sigma = \sqrt{\text{Var}(S_n)} = \sqrt{n \times p \times (1-p)} = \sqrt{100 \times 0.95 \times 0.05} = \sqrt{4.75} \approx 2.18\)

2. 計算閾值

閾值 \(= E[S_n] - k \times \sigma = 95 - 2 \times 2.18 \approx 90\)

(成功次數低於 90 就告警,即失敗超過 10 次)

3. 計算誤報率

\[P(S_n \leq 90) \approx \Phi\left(\frac{90.5 - 95}{2.18}\right) = \Phi(-2.06) \approx 0.020\]

誤報率約 2%

4. 業務評估

2% 意味著每 50 次檢查就會誤報 1 次。

如果監控系統每分鐘檢查一次:

  • 每小時 60 次檢查 → 平均每小時誤報 1.2 次
  • 每天誤報約 29 次

結論:k = 2 這個閾值太鬆了,你會被正常波動吵死,不可接受。


(c-4) 調整閾值,滿足業務需求

(c-3) 告訴你 k = 2 會導致每小時被吵醒 1 次。主管說:「這太誇張了,我希望每週最多被誤報叫醒 1 次。」

k 該調到多少?

解答

從業務需求反推誤報率

  • 每週 = 7 × 24 × 60 = 10,080 分鐘 = 10,080 次檢查
  • 最多誤報 1 次 → 誤報率 ≤ 1/10,080 ≈ 0.01%

反推 k

設閾值為「失敗次數 > \(\mu + k\sigma\)」,誤報率 ≈ \(\Phi(-k)\)

要讓 \(\Phi(-k) \leq 0.0001\),查表得 \(k \approx 3.7\)

結論

從 k = 2 調整到 k = 3.7,誤報率從 2% 降到 0.01%。

以 1 分鐘為週期(n = 12,000):

  • 期望失敗次數 = 600,標準差 ≈ 23.9
  • 原閾值(k=2):600 + 2 × 23.9 = 648
  • 新閾值(k=3.7):600 + 3.7 × 23.9 ≈ 688

告警規則:1 分鐘內失敗超過 688 次才告警。

小結:完整的告警設計流程

回顧整個過程,你完成了一個完整的告警系統設計:

  1. (a) 算出單次請求的期望值 → 建立基準線
  2. (b) 算出變異數 → 知道正常波動範圍
  3. (c-1) 推導完整分布 → 能精確計算任意閾值的誤報率
  4. (c-2) 把單次統計量擴展到週期 → 連接業務場景
  5. (c-3) 給定閾值算誤報率 → 評估方案
  6. (c-4) 給定誤報率反推閾值 → 滿足業務需求

這就是用數學解決實際問題的完整流程。

數學小結:你剛才發現了 Binomial 分布

\(n\) 個獨立 Bernoulli 的和,數學上叫做 Binomial 分布,記作 \(S_n \sim B(n, p)\)

性質 公式
PMF \(P(S_n=k) = \binom{n}{k} p^k (1-p)^{n-k}\)
期望值 \(E[S_n] = np\)
變異數 \(\text{Var}(S_n) = np(1-p)\)

進階挑戰:不知道分布怎麼辦?

3 分大二

前面的推導依賴三個假設:

  1. 每次請求獨立
  2. 每次只有成功或失敗
  3. 成功率固定是 0.95

但 PM 質疑:「這些假設在實際場景中真的成立嗎?」

  • 獨立性可能不成立:如果一台 GPU 掛了,會同時影響很多請求,它們就不是獨立的
  • 成功率可能不固定:尖峰時段負載高,成功率可能下降;凌晨負載低,成功率可能更高
  • 可能有其他複雜因素:網路波動、請求排隊效應...

當這些假設不完全成立時,Binomial 公式就不一定準了。有沒有更穩健的方法?

你需要知道:Chebyshev 不等式——只需要知道期望和變異數,不管分布長什麼樣都成立!

Chebyshev 不等式:對任意分布,

\[P(|X - \mu| \geq k\sigma) \leq \frac{1}{k^2}\]

題目:設 1 分鐘處理 \(n = 1200\) 次請求,失敗次數 \(F\) 的期望 \(\mu = 60\),標準差 \(\sigma = 7.55\)

  1. 用 Chebyshev 不等式估計 \(P(F > 90)\) 的上界
  2. 與 Binomial 精確計算(或常態近似)比較
  3. 討論 Chebyshev 為什麼「保守」
提示

\(F > 90\) 意味著 \(|F - 60| > 30\)。先把 30 換算成幾個標準差。

解答

Step 1:Chebyshev 估計

\(F > 90\) 意味著 \(|F - 60| > 30 = 3.97\sigma\)

\[P(|F - 60| \geq 30) \leq \frac{1}{3.97^2} \approx 0.063\]

所以 \(P(F > 90) \leq 0.063\)(實際更小,因為只考慮右尾)

Step 2:常態近似

\[P(F > 90) = P\left(Z > \frac{90 - 60}{7.55}\right) = P(Z > 3.97) \approx 0.00004\]

Step 3:比較

  • Chebyshev:\(\leq 6.3\%\)(保守)
  • 常態近似:\(\approx 0.004\%\)(精確)
  • 差異:Chebyshev 高估了約 1500 倍!
這個不等式有什麼用?

穩健性:當你不確定分布形式時,Chebyshev 給出最壞情況的保證

考試技巧

  • 題目說「不假設分布」→ 用 Chebyshev
  • 題目說「服從某分布」→ 用精確計算或 CLT
數學小結:Chebyshev 不等式
特性 說明
前提 只需 \(\mu, \sigma\) 存在
公式 \(P(\|X - \mu\| \geq k\sigma) \leq 1/k^2\)
優點 對任意分布成立
缺點 通常很保守(高估機率)
典型應用 不知道分布、穩健估計

(d) 第一次錯誤什麼時候發生?

4 分大三

現在你有了告警公式:「一個週期內錯誤次數超過閾值才告警」。

但貪心的你想更進一步:能不能預測什麼時候可能會報警? 如果週末半夜報警機率高,你得提前跟老闆報備;如果機率很低,你可以安心睡覺。

告警的前提是「有錯誤發生」。所以你想:如果我知道第一次錯誤什麼時候出現,就能評估後續情況——

  • 如果第一次錯誤後接連出錯 → 很可能觸發告警
  • 如果只是偶發性的 → 不會達到閾值,可以放心

你需要知道:平均多少次請求後,會出現第一次錯誤?

題目

\(W\) 為「第一次失敗」發生的位置(例如:第 1 次就失敗則 \(W=1\),前 2 次成功、第 3 次失敗則 \(W=3\))。

  1. 推導 \(P(W = k)\)\(k = 1, 2, 3, \ldots\)
  2. 計算 \(E[W]\)
  3. 如果每秒 200 次請求,平均多久會出現第一次錯誤?
提示

\(W = k\) 表示「前 \(k-1\) 次都成功,第 \(k\) 次失敗」。

解答
  1. \(W = k\) 表示前 \(k-1\) 次成功、第 \(k\) 次失敗:

    \[P(W = k) = p^{k-1} (1-p) = (0.95)^{k-1} (0.05), \quad k = 1, 2, 3, \ldots\]
  2. \(q = 1 - p = 0.05\)

    \[E[W] = \sum_{k=1}^{\infty} k \cdot p^{k-1} q = \frac{1}{q} = \frac{1}{0.05} = 20\]
  3. \(E[W] = 20\) 次請求才會出現第一次錯誤。

    每秒 200 次請求 → 平均 \(20 / 200 = 0.1\) 秒就會出現第一次錯誤。

    結論:單次錯誤非常頻繁(每 0.1 秒就有一次),這是正常現象,不代表系統出問題。

這個計算有什麼用?

理解「單次錯誤」的意義:平均每 0.1 秒就會出現一次錯誤,這是 5% 失敗率的正常表現。

這就是為什麼 © 題用「累積策略」:單次錯誤太常見了,只有「一段時間內錯誤次數異常多」才值得告警。

數學小結:你剛才發現了 Geometric 分布

「等到第一次失敗」的位置,數學上叫做 Geometric 分布,記作 \(W \sim \text{Geom}(q)\)\(q = 1-p\) 是失敗機率)。

性質 公式
PMF \(P(W=k) = p^{k-1} q\)\(k = 1, 2, \ldots\)
期望值 \(E[W] = 1/q\)
變異數 \(\text{Var}(W) = p/q^2\)
無記憶性 \(P(W > m+n \mid W > m) = P(W > n)\)

進階:無記憶性證明

2 分大二

你在顧慮一件事:某次的 API 錯誤跟下一次的 API 錯誤會有關係嗎?

如果有關係(比如一個錯誤引發連鎖反應、系統「累了」更容易出錯),前面的公式就全部不能用了——Bernoulli、Binomial、Geometric 都假設每次請求是獨立的。

你需要知道:錯誤之間是獨立的嗎?前面發生了什麼,會不會影響後面?

題目:證明 Geometric 分布的無記憶性:

\[P(W > m+n \mid W > m) = P(W > n)\]
證明
\[P(W > m+n \mid W > m) = \frac{P(W > m+n)}{P(W > m)} = \frac{(1-q)^{m+n}}{(1-q)^m} = (1-q)^n = P(W > n)\]

其中 \(P(W > k) = (1-q)^k\) 是「前 \(k\) 次都成功」的機率。

這個證明有什麼用?

結論:不論已經連續成功多少次,「還要多久才失敗」的分布完全相同

實務意義:告警系統可以放心「重置計數器」——過去 50 次成功不影響接下來的判斷。 這就是 Geometric 分布的無記憶性,也是它區別於其他離散分布的標誌性質。

類比:擲公平硬幣已經連續 10 次正面,下一次正面的機率仍是 50%——不是「該出反面了」!

小結:你完成了「第一次錯誤」模組

現在你知道:

  1. 第一次錯誤平均 0.1 秒就會出現(每秒 200 次請求、5% 失敗率)
  2. 錯誤之間是獨立的——前面發生什麼不影響後面

結論:單次錯誤是家常便飯,不值得大驚小怪。只有「一段時間內錯誤異常多」才需要告警。

你可以安心睡覺了——至少在告警響之前。


(e) 連續錯誤偵測

4 分大三

你完成了兩個模組,但回頭看發現一個問題:目前的告警邏輯假設錯誤「均勻分布」在整個週期內

但現實中可能有這種情況:「第一次出錯後就一直錯」——系統真的壞了。

在「均勻」的邏輯下,這種連續錯誤會被推遲處理:你得等整個週期結束,統計完錯誤總數,才會告警。但連續錯誤很可能代表系統出了大問題,你希望在事態擴大之前就收到通知。

你當然可以透過切更細的時間片段來解決——把 1 分鐘改成 10 秒、甚至每 100 次請求就檢查一次。但這有兩個問題:

  1. 樣本變小,波動變大:週期越短,正常波動越容易觸發閾值 → 誤報率上升
  2. 治標不治本:你關心的是「連續錯誤」這個模式,不是「短週期內錯誤多」

更直接的做法:不看週期,直接監控「連續錯了幾次」。

問題:連續錯 \(r\) 次就通知——\(r\) 應該設多少?累積到第 \(r\) 次錯誤,平均需要多少次請求?

題目

\(T_r\) 為「第 \(r\) 次失敗」發生的位置。

  1. 說明 \(T_r\)\(W\)(第一次失敗的位置)的關係
  2. 推導 \(P(T_r = k)\)\(k = r, r+1, r+2, \ldots\)
  3. 計算 \(E[T_r]\)
  4. \(r = 5\)\(q = 0.05\),平均需要多少次請求才會告警?
提示

\(T_r = k\) 表示「前 \(k-1\) 次中恰好 \(r-1\) 次失敗,第 \(k\) 次是第 \(r\) 次失敗」。

解答
  1. \(T_r\) 可以看成 \(r\) 個獨立 Geometric 的和:\(T_r = W_1 + W_2 + \cdots + W_r\)

    其中 \(W_i\) 是「第 \(i-1\) 次失敗後,等到第 \(i\) 次失敗的額外請求數」。

  2. \(T_r = k\) 表示「前 \(k-1\) 次中恰好 \(r-1\) 次失敗,第 \(k\) 次失敗」:

    \[P(T_r = k) = \binom{k-1}{r-1} q^r p^{k-r}, \quad k = r, r+1, \ldots\]
  3. 由於 \(T_r = \sum_{i=1}^r W_i\),各 \(W_i\) 獨立且 \(E[W_i] = 1/q\)

    \[E[T_r] = r \cdot E[W] = \frac{r}{q}\]
  4. \(r = 5\)\(q = 0.05\)

    \[E[T_5] = \frac{5}{0.05} = 100\]

    平均需要 100 次請求才會累積到 5 次失敗。

這個計算有什麼用?

設計折衷告警策略

\(r\) \(E[T_r]\) 平均多久告警一次(假設 200 QPS)
1 20 0.1 秒
3 60 0.3 秒
5 100 0.5 秒
10 200 1 秒

選擇 \(r\) 時需要權衡:\(r\) 越大,誤報越少,但發現故障越慢。

數學小結:你剛才發現了 Negative Binomial 分布

「等到第 \(r\) 次失敗」的位置,數學上叫做 Negative Binomial 分布,記作 \(T_r \sim \text{NB}(r, q)\)

性質 公式
PMF \(P(T_r=k) = \binom{k-1}{r-1} q^r p^{k-r}\)\(k = r, r+1, \ldots\)
期望值 \(E[T_r] = r/q\)
變異數 \(\text{Var}(T_r) = rp/q^2\)
與 Geometric 關係 \(T_r = W_1 + \cdots + W_r\)\(r\) 個獨立 Geom 的和)

(f) 策略評估:每種能給多少信心?

4 分碩一

現在你手上有多種策略:

  1. 累積 \(n\) 次看失敗比例:用 Binomial 分布
  2. 監控第一次錯誤時間:用 Geometric 分布
  3. 連續 \(r\) 次錯誤才告警:用 Negative Binomial 分布

現代系統通常不是只選一種,而是多種策略並行,應對不同情況。但在部署之前,你需要知道:每種策略能給你多少信心?

  • 誤報率(Type I Error):系統正常時,被錯誤告警的機率
  • 漏報率(Type II Error):系統異常時,沒有告警的機率

這就是假設檢定框架的用武之地。

設正常狀態下失敗率 \(q_0 = 0.05\),異常狀態下失敗率 \(q_1 = 0.15\)

使用假設檢定框架:\(H_0\): 系統正常(\(q = q_0\)),\(H_1\): 系統異常(\(q = q_1\)


(f-1) Binomial 策略:累積 n 次看失敗比例

題目:對於「累積 \(n = 100\) 次,失敗超過 \(k\) 次就告警」的策略:

  1. 推導誤報率 \(\alpha(k)\) 和漏報率 \(\beta(k)\) 的公式
  2. 畫出 \(\alpha\)\(\beta\) 關於 \(k\) 的變化曲線(示意圖即可)
  3. 若要求 \(\alpha \leq 0.01\),求最小的 \(k\);此時 \(\beta\) 是多少?
解答
  1. 誤報率和漏報率:

    \[\alpha(k) = P(F_n > k \mid H_0) = \sum_{j=k+1}^{n} \binom{n}{j} (0.05)^j (0.95)^{n-j}\]
    \[\beta(k) = P(F_n \leq k \mid H_1) = \sum_{j=0}^{k} \binom{n}{j} (0.15)^j (0.85)^{n-j}\]
  2. 曲線特性:

    • \(k\) 增大 → \(\alpha\) 減小(更不容易誤報)
    • \(k\) 增大 → \(\beta\) 增大(更容易漏報)
    • 需要找平衡點
  3. \(n = 100\),求 \(\alpha \leq 0.01\)

    使用常態近似,\(H_0\)\(F_n \approx N(5, 4.75)\)

    \(k \geq 5 + 2.33 \times 2.18 = 10.1\),取 \(k = 11\)

    此時 \(\beta \approx \Phi\left(\frac{11 - 15}{\sqrt{12.75}}\right) = \Phi(-1.12) \approx 0.13\)

    結論\(\alpha = 0.01\) 時,\(\beta = 13\%\)(漏掉 13% 的故障)


(f-2) Geometric 策略:監控第一次錯誤時間

題目:對於「第一次錯誤在 \(k\) 次內就告警」的策略:

  1. 推導誤報率 \(\alpha(k)\) 和漏報率 \(\beta(k)\) 的公式
  2. 若要求 \(\alpha \leq 0.01\)\(k\) 應該設多少?此時 \(\beta\) 是多少?
  3. 這個策略適合什麼情況?
解答
  1. \(W\) = 第一次錯誤發生的位置

    • 正常時 \(W \sim \text{Geom}(q_0)\)\(P(W = j) = (1-q_0)^{j-1} q_0\)
    • 異常時 \(W \sim \text{Geom}(q_1)\)

    告警條件:\(W \leq k\)(在 \(k\) 次內出現錯誤就告警)

    \[\alpha(k) = P(W \leq k \mid q_0) = 1 - (1-q_0)^k = 1 - 0.95^k\]
    \[\beta(k) = P(W > k \mid q_1) = (1-q_1)^k = 0.85^k\]
  2. \(\alpha \leq 0.01\)

    \(1 - 0.95^k \leq 0.01 \Rightarrow 0.95^k \geq 0.99 \Rightarrow k \leq \frac{\ln 0.99}{\ln 0.95} \approx 0.2\)

    問題\(k\) 必須是正整數,但 \(k = 1\)\(\alpha = 0.05 > 0.01\)

    結論:這個策略無法在保持低誤報率的同時有效偵測。

  3. 適用情況:

    • **不適合**作為主要告警策略(誤報率太高)
    • **適合**作為「快速預警」:系統剛啟動時,第一次錯誤是否來得太快?
    • 配合其他策略使用,而非單獨使用

(f-3) Negative Binomial 策略:連續 r 次錯誤告警

題目:對於「累積 \(r\) 次錯誤在 \(k\) 次內就告警」的策略(取 \(r = 3\)):

  1. 推導誤報率 \(\alpha(k)\) 和漏報率 \(\beta(k)\) 的公式
  2. 若要求 \(\alpha \leq 0.01\)\(k\) 應該設多少?此時 \(\beta\) 是多少?
  3. 與 Binomial 策略相比,這個策略的特點是什麼?
解答
  1. \(T_r\) = 第 \(r\) 次錯誤發生的位置

    • 正常時 \(T_r \sim \text{NB}(r, q_0)\)
    • 異常時 \(T_r \sim \text{NB}(r, q_1)\)

    告警條件:\(T_r \leq k\)(在 \(k\) 次內累積 \(r\) 次錯誤就告警)

    \[\alpha(k) = P(T_r \leq k \mid q_0) = \sum_{j=r}^{k} \binom{j-1}{r-1} q_0^r (1-q_0)^{j-r}\]
    \[\beta(k) = P(T_r > k \mid q_1) = 1 - \sum_{j=r}^{k} \binom{j-1}{r-1} q_1^r (1-q_1)^{j-r}\]
  2. \(r = 3\),要 \(\alpha \leq 0.01\)

    需要數值計算。\(k = 20\) 時:

    \(\alpha(20) = P(T_3 \leq 20 \mid q_0 = 0.05) \approx 0.008 < 0.01\)

    \(\beta(20) = P(T_3 > 20 \mid q_1 = 0.15) \approx 0.18\)

    結論\(k = 20\) 時,誤報率 0.8%,漏報率 18%

  3. 與 Binomial 比較:

    特性 Binomial(固定窗口) Negative Binomial(累積錯誤)
    偵測速度 固定(等窗口結束) 可變(錯誤多就快)
    對連續錯誤 不敏感 敏感
    實作複雜度 簡單 稍複雜
    適用場景 穩定監控 快速偵測突發故障
三種策略總結
策略 分布 優點 缺點 適用場景
累積 n 次 Binomial 穩定、可控 偵測延遲固定 常態監控
第一次錯誤 Geometric 反應最快 誤報率高 快速預警
累積 r 次錯誤 Neg. Binomial 對連續錯誤敏感 計算稍複雜 突發故障偵測

實務建議:多種策略並行,各司其職。


進階挑戰:告警響了,系統真的壞了嗎?

3 分大三

告警系統上線一陣子後,你觀察到一個現象:告警響了,但檢查後發現系統其實沒壞

這讓你開始思考:每次告警響起,有多少機率是「真的壞了」,又有多少機率是「白跑一趟」?

注意,這跟前面算的東西不一樣:

  • 前面算的是「系統壞了 → 告警會響嗎?」(靈敏度
  • 現在要問的是「告警響了 → 系統真的壞了嗎?」(後驗機率

這是完全不同的問題!

你需要知道:如何從「告警響了」反推「系統真的壞了」的機率?

題目:假設:

  • 系統故障的先驗機率 \(P(\text{故障}) = 0.01\)(系統 99% 時間正常)
  • 故障時告警響起的機率 \(P(\text{告警}|\text{故障}) = 0.95\)(靈敏度 95%)
  • 正常時告警響起的機率 \(P(\text{告警}|\text{正常}) = 0.02\)(誤報率 2%)

  • 用 Bayes' Theorem 計算 \(P(\text{故障}|\text{告警})\)

  • 解釋為什麼結果這麼低(這叫「基率謬誤」)
  • 若要使 \(P(\text{故障}|\text{告警}) > 50\%\),誤報率應降到多少?
解答

Step 1:Bayes 公式

\[P(\text{故障}|\text{告警}) = \frac{P(\text{告警}|\text{故障}) \cdot P(\text{故障})}{P(\text{告警})}\]

Step 2:計算 \(P(\text{告警})\)(全機率公式)

\[P(\text{告警}) = P(\text{告警}|\text{故障})P(\text{故障}) + P(\text{告警}|\text{正常})P(\text{正常})$$ $$= 0.95 \times 0.01 + 0.02 \times 0.99 = 0.0095 + 0.0198 = 0.0293\]

Step 3:後驗機率

\[P(\text{故障}|\text{告警}) = \frac{0.0095}{0.0293} \approx 32.4\%\]

基率謬誤解釋

雖然告警靈敏度高達 95%,但因為系統故障本身很罕見(1%),「正常但誤報」的絕對數量(\(0.99 \times 0.02 = 1.98\%\))遠大於「故障且正確告警」(\(0.01 \times 0.95 = 0.95\%\))。

降低誤報率的計算

\(P(\text{告警}|\text{正常}) = x\),要使後驗 > 50%:

\[\frac{0.0095}{0.0095 + 0.99x} > 0.5 \Rightarrow 0.0095 > 0.00475 + 0.495x \Rightarrow x < 0.0096\]

誤報率需降到 0.96% 以下(從原來的 2% 降低一半以上)。

這個計算有什麼用?

SRE 的日常:告警響了,但大部分時候系統沒壞——這就是「基率謬誤」的真實體現。

改善方向

策略 效果
降低誤報率 最有效!從 2% 降到 1% 就能大幅提升後驗機率
提高靈敏度 效果有限(已經 95% 了)
多重確認 連續 2 次告警才行動,等效於降低誤報率
數學小結:Bayes' Theorem
概念 符號 本題意義
先驗 \(P(A)\) 系統故障率(1%)
似然 \(P(B\|A)\) 靈敏度/誤報率
後驗 \(P(A\|B)\) 收到告警後故障的機率
公式 \(P(A\|B) = \frac{P(B\|A)P(A)}{\sum_i P(B\|A_i)P(A_i)}\) 全機率 + 條件機率

關鍵洞察:後驗機率不只取決於似然(靈敏度),更取決於先驗(基率)。 當事件很罕見時(低基率),即使檢測器很準,「陽性結果為真」的機率仍可能很低。


第 1 題小結:你的告警工具箱

凌晨三點,你被告警叫醒
「系統掛了嗎?」
    ├─► 需要知道:正常失敗率 → 工具:Bernoulli(E[X], Var(X))
「波動多大算異常?」
    ├─► 需要知道:失敗次數的分布 → 工具:Binomial
「一失敗就告警?」
    ├─► 需要知道:第一次失敗何時發生 → 工具:Geometric
「太敏感,累積 r 次呢?」
    ├─► 需要知道:第 r 次失敗何時發生 → 工具:Negative Binomial
「哪種策略最好?」
    ├─► 工具:假設檢定(平衡誤報與漏報)
「告警響了,系統真的壞了嗎?」
    └─► 工具:Bayes' Theorem(從觀察反推狀態)

分布關係圖

Bernoulli(p)
    │ n 個獨立的和
Binomial(n, p)

Bernoulli(p) → 等到第一次失敗 → Geometric(1-p)
                                    │ r 個獨立的和
                              Negative Binomial(r, 1-p)

< 返回目錄 | 下一題:批次處理策略 >


  1. PagerDuty 是一個事件管理與告警平台,負責整合各種監控系統的告警、管理 On-call 排班、並透過電話/簡訊/Slack 通知值班人員。簡單說:它就是那個凌晨三點叫醒 SRE 的工具。類似產品還有 Opsgenie、VictorOps 等。