错误预算怎么算?一次 6 秒的事故消耗多少预算?燃烧速率告警怎么设窗口和阈值?快燃烧和慢燃烧各能发现什么、迟多久?这篇用 Prometheus 3.15.0 和已知错误数的模拟流量逐项算出来。
SLO | 30 天允许的完全不可用时间 | 秒 | 错误预算(允许的错误比例) --------+----------------+---------+-------------- 99% | 432.0 分钟 | 25920 秒 | 0.01000 99.9% | 43.2 分钟 | 2592 秒 | 0.00100 99.99% | 4.3 分钟 | 259 秒 | 0.00010 99.999% | 0.4 分钟 | 26 秒 | 0.00001 每增加一个 9,预算缩小为原来的十分之一;错误预算是“允许失败的请求比例”,不是时间:没有全部挂掉、只是一部分请求失败时,按失败的请求占比消耗预算 30 天窗口下常见的多窗口燃烧速率告警取值(长窗口 / 短窗口,燃烧速率阈值),以及按“燃烧速率 × 窗口 ÷ 30 天”算出来的、触发时已经消耗的预算比例(算出来的): 窗口(长 / 短) | 燃烧速率阈值 | 触发时已消耗的 30 天预算比例 -------------+--------+----------------- 1 小时 / 5 分钟 | 14.4× | 2% 6 小时 / 30 分钟 | 6× | 5% 3 天 / 6 小时 | 1× | 10%
每多一个 9,预算缩小为 1/10;预算是允许失败的请求比例。
时刻 | 累计错误(程序计数) | 已消耗的预算 | 剩余预算 | Prometheus increase 算出的累计错误 --------+------------+--------+------+---------------------------- 第 29 秒 | 5 | 1% | +99% | 5 第 37 秒 | 366 | 61% | +39% | 372 第 99 秒 | 378 | 63% | +37% | 380 第 130 秒 | 558 | 93% | +7% | 560 第 161 秒 | 738 | 123% | -23% | 740 第 299 秒 | 766 | 128% | -28% | 767 预算按“失败的请求数”消耗:事故 A 只有 6 s、但 30% 的请求失败;事故 B 错误率只有 3%、但持续 60 s;两者各消耗了预算的相当一部分,再加上基线的 0.1%,到窗口结束时预算已经用完。两者换成时间的话,A 相当于 6 × 0.3 = 1.8 s 的完全不可用(算出来的)
预算按失败的请求数消耗,短而严重的事故和长而轻微的事故可以消耗同样多的预算。
告警条件 | 事故 A(30% 失败,6 s) | 事故 B(3% 失败,60 s) | 事故之外的触发点数
---------------------------------+-------------------------------------------------+-----------------------------------------------------+----------
(a)快燃烧:燃烧速率(12 s)> 10 且(2 s)> 10 | 第 34 秒起(开始后 +4 s,此时已消耗预算 61%),第 36 秒止(结束后 +0 s) | 没有触发 | 0
(b)慢燃烧:燃烧速率(60 s)> 2 且(6 s)> 2 | 第 32 秒起(开始后 +2 s,此时已消耗预算 41%),第 40 秒止(结束后 +4 s) | 第 139 秒起(开始后 +39 s,此时已消耗预算 104%),第 161 秒止(结束后 +1 s) | 0
(c)朴素:10 s 错误率 > 5% | 第 32 秒起(开始后 +2 s,此时已消耗预算 41%),第 43 秒止(结束后 +7 s) | 没有触发 | 0
事故 A 的燃烧速率是 30,B 是 3:快燃烧(阈值 10)只看得到 A,慢燃烧(阈值 2)两个都看得到但要等长窗口里累积到阈值——B 的发现比 A 晚得多;朴素的“10 s 错误率 > 5%”看不到 3% 的持续错误。短窗口的作用是事故结束之后让告警尽快清除
ERRORS {}快燃烧发现短而严重的事故,慢燃烧发现长而轻微的事故;短窗口让告警在事故结束后很快清除;窗口和阈值要按预算窗口设计。