3、误差预算核心指标:SLI指标设计、燃烧速率(Burn Rate)与剩余预算的计算逻辑
误差预算(Error Budget)是 SRE 实践的核心量化工具,它将系统可靠性从“尽可能高”的模糊目标,转化为可度量、可管理的工程指标。本章聚焦于误差预算台账中的三个核心要素:SLI(Service Level Indicator)、燃烧速率(Burn Rate)与剩余预算(Remaining Budget)。理解这三者的定义、设计原则与计算逻辑,是构建有效告警与容量规划的基础。
3.1 SLI 指标设计:从原始数据到可聚合的可靠性度量
SLI 是服务可靠性的直接量化指标,通常定义为“好事件”占总事件的比例。设计 SLI 时,需要明确三个要素:测量对象、好事件定义与时间窗口。
3.1.1 常见 SLI 类型与 PromQL 表达
| SLI 类型 | 好事件定义 | 典型 PromQL 表达式(原始计数) |
|---|---|---|
| 请求成功率 | HTTP 状态码 < 500 | sum(rate(http_requests_total{status!~"5.."}[5m])) |
| 请求延迟(P99) | 延迟 <= 200ms | histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) |
| 可用性 | 成功探针响应 | avg(probe_success) |
| 吞吐量 | 请求数 > 阈值 | sum(rate(http_requests_total[5m])) |
在误差预算台账中,我们通常将 SLI 聚合为时间窗口内的好事件比例:
# 计算过去 30 天的请求成功率 SLI
(
sum(rate(http_requests_total{status!~"5.."}[30d]))
/
sum(rate(http_requests_total[30d]))
)
3.1.2 SLI 设计检查清单
- 可测量性:指标是否可以从现有监控系统直接获取或计算?
- 用户相关性:指标是否反映用户实际体验?
- 可聚合性:指标是否支持按服务、版本、区域等维度进行聚合?
- 稳定性:指标在正常波动下是否保持稳定,避免频繁触发告警?
3.2 燃烧速率(Burn Rate)计算逻辑
燃烧速率衡量的是错误预算消耗的速度。它定义为“实际错误率”与“SLO 允许的错误率”之比。当燃烧速率 > 1 时,表示错误预算正在以快于预期的速度消耗。
3.2.1 燃烧速率公式
Burn Rate = (1 - SLI) / (1 - SLO)
其中:
- SLI:当前时间窗口内的实际好事件比例(例如 0.995)
- SLO:目标好事件比例(例如 0.999)
示例:若 SLO 为 99.9%(0.999),当前 SLI 为 99.5%(0.995),则:
Burn Rate = (1 - 0.995) / (1 - 0.999) = 0.005 / 0.001 = 5
这意味着错误预算的消耗速度是预期的 5 倍。
3.2.2 多窗口燃烧速率告警策略
在实际 SRE 实践中,通常使用多窗口(例如 1 小时、5 小时、30 小时)的燃烧速率来触发不同级别的告警。下表展示了 Google SRE 推荐的典型配置:
| 告警级别 | 时间窗口 | 燃烧速率阈值 | 预算消耗比例 | 响应时间 |
|---|---|---|---|---|
| Page(紧急) | 1 小时 | >= 14.4 | 2% 预算在 1 小时内烧完 | 立即 |
| Page(紧急) | 5 小时 | >= 6 | 5% 预算在 5 小时内烧完 | 立即 |
| Ticket(非紧急) | 30 小时 | >= 1 | 预算在 30 小时内烧完 | 下一个工作日 |
rate() 或 increase() 函数,并确保时间窗口与 SLO 周期对齐。避免在短窗口内使用 avg_over_time() 直接聚合 SLI,这会导致燃烧速率计算失真。
3.3 剩余预算(Remaining Budget)计算逻辑
剩余预算表示在 SLO 周期内,系统还能容忍多少错误而不违反 SLO。它是误差预算台账中最直观的“健康度”指标。
3.3.1 剩余预算公式
Remaining Budget = 1 - (Total Errors / Allowed Errors)
其中:
- Total Errors:SLO 周期内累计的错误事件数
- Allowed Errors:SLO 周期内允许的最大错误事件数 = 总事件数 × (1 - SLO)
示例:若 SLO 周期为 30 天,总请求数为 10,000,000,SLO 为 99.9%,则允许错误数为 10,000。若当前已发生 2,000 个错误,则:
Remaining Budget = 1 - (2000 / 10000) = 0.8 = 80%
表示还有 80% 的预算可用。
3.3.2 PromQL 实现剩余预算
# 计算 30 天窗口内的剩余预算
(
1
-
(
sum(increase(errors_total[30d]))
/
(
sum(increase(requests_total[30d]))
*
(1 - 0.999) # SLO = 99.9%
)
)
)
3.4 核心指标关系图
下图展示了 SLI、SLO、燃烧速率与剩余预算之间的逻辑关系:
3.5 实践案例:构建误差预算台账
假设某 API 服务的 SLO 为 99.9%(30 天滚动窗口),我们需要在 Prometheus 中构建误差预算台账。以下是一个完整的 PromQL 查询集:
# 1. SLI:30 天请求成功率
sli:request_success_rate:30d = (
sum(rate(http_requests_total{status!~"5.."}[30d]))
/
sum(rate(http_requests_total[30d]))
)
# 2. 燃烧速率:1 小时窗口
burn_rate:1h = (
(1 - sli:request_success_rate:1h)
/
(1 - 0.999)
)
# 3. 剩余预算
remaining_budget:30d = (
1
-
(
sum(increase(http_requests_total{status=~"5.."}[30d]))
/
(
sum(increase(http_requests_total[30d]))
* 0.001
)
)
)
rate() 函数时,时间窗口应至少为指标采集间隔的 4 倍,以避免数据稀疏导致的抖动。对于 30 天窗口,建议使用 increase() 而非 rate(),因为 increase() 直接返回累计值,更适合预算计算。
3.6 常见陷阱与避坑指南
- 陷阱 1:使用
avg_over_time()聚合 SLI 时,忽略了时间窗口内的请求量权重,导致 SLI 失真。应使用sum(rate(...)) / sum(rate(...))形式。 - 陷阱 2:燃烧速率计算中,时间窗口与 SLO 周期不匹配。例如,使用 1 小时窗口计算 30 天 SLO 的燃烧速率,可能导致误告警。
- 陷阱 3:剩余预算为负时,未考虑“预算透支”后的恢复机制。实际上,剩余预算为负后,系统仍可正常运行,但需要在后续周期内通过更高的可靠性来“偿还”。