2. Prometheus 误差预算计算:基于 Histogram 的 SLI 计算、基于 Counter 的 SLI 计算、误差预算率公式推导
误差预算(Error Budget)是 SRE 实践中的核心量化指标,它定义了服务在给定时间窗口内允许的最大不可用或低质量时间。要准确计算误差预算,首先需要从 Prometheus 指标中提取服务等级指标(SLI),然后根据 SLI 与 SLO 目标值推导出误差预算率。本章将系统讲解基于 Histogram 和 Counter 两种主流数据类型的 SLI 计算方法,并完成误差预算率的完整公式推导。
2.1 基于 Histogram 的 SLI 计算
Histogram(直方图)是 Prometheus 中最常用的 SLI 数据源,特别适用于延迟类指标(如请求耗时、响应时间)。Histogram 通过多个桶(bucket)记录观测值的分布,每个桶统计小于等于该桶上界值的样本数量。
2.1.1 Histogram 数据结构与 SLI 提取
典型的 HTTP 请求延迟 Histogram 指标如下:
# HELP http_request_duration_seconds request latency histogram
# TYPE http_request_duration_seconds histogram
http_request_duration_seconds_bucket{le="0.1"} 2400
http_request_duration_seconds_bucket{le="0.25"} 4500
http_request_duration_seconds_bucket{le="0.5"} 6200
http_request_duration_seconds_bucket{le="1.0"} 7100
http_request_duration_seconds_bucket{le="2.5"} 7350
http_request_duration_seconds_bucket{le="5.0"} 7400
http_request_duration_seconds_bucket{le="+Inf"} 7420
http_request_duration_seconds_count 7420
http_request_duration_seconds_sum 1283.5
要计算延迟类 SLI(例如:99% 的请求在 500ms 内完成),我们需要从 Histogram 中提取“良好请求”的数量。良好请求定义为延迟 ≤ SLO 阈值的请求。假设 SLO 阈值为 0.5 秒,则良好请求数即为 le="0.5" 桶的累积值。
2.1.2 基于 Histogram 的 SLI 计算步骤
- 确定 SLO 阈值:例如延迟 SLO 为 “99% 的请求在 500ms 内完成”,则阈值为 0.5 秒。
- 提取良好请求数:使用 PromQL 查询
http_request_duration_seconds_bucket{le="0.5"}。 - 提取总请求数:使用
http_request_duration_seconds_count。 - 计算 SLI 比率:SLI = 良好请求数 / 总请求数。
对应的 PromQL 表达式:
# 延迟 SLI(良好请求占比)
(
sum(rate(http_request_duration_seconds_bucket{le="0.5"}[5m]))
/
sum(rate(http_request_duration_seconds_count[5m]))
)
2.1.3 Histogram 计算的注意事项
| 注意事项 | 说明 |
|---|---|
| 桶边界选择 | SLO 阈值必须与某个桶边界对齐,否则无法精确计算良好请求数。若阈值介于两个桶之间,需使用线性插值估算。 |
| 累积计数特性 | Histogram 的桶是累积的,le="0.5" 包含所有 ≤0.5 秒的请求,无需额外累加。 |
| 速率 vs 原始值 | 计算 SLI 时通常使用 rate() 或 increase() 函数,避免因重启或时间窗口导致计数偏差。 |
| 多维度聚合 | 若服务有多个实例或端点,需使用 sum() 聚合所有相关维度。 |
le="0.5",避免插值误差。
2.2 基于 Counter 的 SLI 计算
Counter(计数器)适用于可用性、错误率等累加型指标。与 Histogram 不同,Counter 不提供分布信息,而是直接记录事件发生的次数。基于 Counter 的 SLI 计算通常用于“成功/失败”二元判定场景。
2.2.1 Counter 数据结构与 SLI 提取
典型的 HTTP 请求状态 Counter 指标如下:
# HELP http_requests_total total number of HTTP requests
# TYPE http_requests_total counter
http_requests_total{status="200"} 15000
http_requests_total{status="404"} 120
http_requests_total{status="500"} 35
要计算可用性 SLI(例如:99.9% 的请求成功),我们需要将状态码为 2xx/3xx 的请求视为成功,其余视为失败。
2.2.2 基于 Counter 的 SLI 计算步骤
- 定义成功条件:例如 HTTP 状态码为 2xx 或 3xx 视为成功。
- 提取成功请求数:使用 PromQL 过滤成功状态码并求和。
- 提取总请求数:所有状态码的请求总数。
- 计算 SLI 比率:SLI = 成功请求数 / 总请求数。
对应的 PromQL 表达式:
# 可用性 SLI(成功请求占比)
(
sum(rate(http_requests_total{status=~"2[0-9][0-9]|3[0-9][0-9]"}[5m]))
/
sum(rate(http_requests_total[5m]))
)
2.2.3 Counter 与 Histogram 的对比
| 对比维度 | Histogram | Counter |
|---|---|---|
| 适用场景 | 延迟、响应时间等分布型指标 | 可用性、错误率等累加型指标 |
| 数据粒度 | 提供分布信息(多桶) | 仅提供总数 |
| SLI 计算方式 | 良好请求数 = 桶值(le ≤ 阈值) | 成功请求数 = 过滤条件求和 |
| 精度 | 受桶边界影响,可能需插值 | 精确计数,无分布误差 |
| 存储开销 | 较高(多桶 + 多标签) | 较低(单指标 + 标签) |
2.3 误差预算率公式推导
误差预算率(Error Budget Rate)是衡量 SLO 合规状态的核心指标,它表示在给定时间窗口内,服务已经消耗的误差预算比例。当误差预算率接近或超过 100% 时,意味着服务正在违反 SLO。
2.3.1 核心变量定义
| 变量 | 含义 | 单位 |
|---|---|---|
| SLO_target | 服务等级目标(例如 99.9%) | 百分比 |
| SLI | 实际测量的服务等级指标 | 百分比 |
| total_requests | 时间窗口内的总请求数 | 计数 |
| good_requests | 时间窗口内的良好请求数 | 计数 |
| bad_requests | 时间窗口内的不良请求数(bad = total - good) | 计数 |
| error_budget_total | 时间窗口内允许的最大不良请求数 | 计数 |
| error_budget_consumed | 时间窗口内已发生的不良请求数 | 计数 |
| error_budget_rate | 误差预算消耗率(已消耗 / 总预算) | 百分比 |
2.3.2 公式推导过程
步骤 1:计算总误差预算
总误差预算 = 时间窗口内允许的不良请求数。根据 SLO 定义:
error_budget_total = total_requests × (1 - SLO_target)
例如,若 SLO_target = 99.9%,则允许的不良请求比例为 0.1%。
步骤 2:计算已消耗的误差预算
已消耗的误差预算 = 实际发生的不良请求数:
error_budget_consumed = bad_requests = total_requests - good_requests
步骤 3:计算误差预算率
误差预算率 = 已消耗预算 / 总预算:
error_budget_rate = error_budget_consumed / error_budget_total
代入变量:
error_budget_rate = (total_requests - good_requests) / (total_requests × (1 - SLO_target))
化简为:
error_budget_rate = (1 - SLI) / (1 - SLO_target)
其中 SLI = good_requests / total_requests。
2.3.3 公式解读与示例
- 当 SLI = SLO_target 时:error_budget_rate = 1,表示预算刚好用完。
- 当 SLI > SLO_target 时:error_budget_rate < 1,表示预算有剩余。
- 当 SLI < SLO_target 时:error_budget_rate > 1,表示预算超支,SLO 被违反。
示例计算:
假设 SLO_target = 99.9%,当前 SLI = 99.5%:
error_budget_rate = (1 - 0.995) / (1 - 0.999) = 0.005 / 0.001 = 5.0
这意味着误差预算消耗率达到了 500%,服务严重违反 SLO。
2.4 误差预算计算流程总览
下图展示了从原始指标到误差预算率的完整计算流程:
2.5 误差预算率在 PromQL 中的实现
将上述公式转换为 PromQL 查询语句,即可实时计算误差预算率:
# 基于 Histogram 的误差预算率(延迟 SLO 示例)
(
1 - (
sum(rate(http_request_duration_seconds_bucket{le="0.5"}[5m]))
/
sum(rate(http_request_duration_seconds_count[5m]))
)
)
/
(
1 - 0.999 # SLO_target = 99.9%
)
# 基于 Counter 的误差预算率(可用性 SLO 示例)
(
1 - (
sum(rate(http_requests_total{status=~"2[0-9][0-9]|3[0-9][0-9]"}[5m]))
/
sum(rate(http_requests_total[5m]))
)
)
/
(
1 - 0.999 # SLO_target = 99.9%
)
record: job:error_budget_rate:ratio_5m。
通过本章的学习,你已经掌握了基于 Histogram 和 Counter 的 SLI 计算方法,以及误差预算率的完整公式推导。这些知识是后续告警降噪策略和阈值联动设计的基础。