3. 误差预算指标定义:SLI指标选取、误差预算计算公式、台账数据结构设计
误差预算(Error Budget)是SRE实践中的核心量化管理工具。它定义了服务在特定时间窗口内允许的最大不可用时间或性能降级量。要构建一个可观测的误差预算台账,必须依次完成三个关键步骤:选取正确的SLI指标、定义误差预算计算公式、设计台账数据结构。本章将逐一拆解这些环节,并给出可直接落地的Exporter采集链路方案。
3.1 SLI指标选取原则与常见类型
SLI(Service Level Indicator)是服务质量的直接度量。选取SLI时应遵循以下原则:
- 用户视角优先:度量指标必须反映终端用户的真实体验,而非仅关注基础设施健康度。
- 可采集、可计算:指标必须能从Exporter或APM工具中稳定获取,且计算逻辑清晰。
- 覆盖核心路径:优先覆盖用户请求的主链路,避免将边缘功能纳入核心SLO。
- 避免指标膨胀:每个服务建议选取1~3个核心SLI,过多指标会导致台账维护成本剧增。
下表列出了生产环境中常见的SLI类型及其典型采集方式:
| SLI类型 | 度量维度 | 典型Exporter指标 | 采集方式 |
|---|---|---|---|
| 请求成功率 | HTTP 2xx/4xx/5xx 比例 | http_requests_total{status=~"2..|4.."} |
Prometheus HTTP Exporter |
| 请求延迟 | P50/P95/P99 响应时间 | http_request_duration_seconds{quantile="0.99"} |
Histogram 聚合 |
| 吞吐量 | 每秒请求数 (RPS) | rate(http_requests_total[1m]) |
PromQL 即时查询 |
| 错误预算消耗率 | 单位时间错误量 | errors_total / total_requests |
自定义Exporter计算 |
| 可用性 | 服务健康检查通过率 | up{job="api-server"} |
Blackbox Exporter |
实战建议:对于大多数Web服务,推荐至少选取请求成功率和P99延迟两个SLI。成功率反映功能可用性,延迟反映性能体验,两者结合能覆盖90%以上的用户故障场景。
3.2 误差预算计算公式与时间窗口
误差预算的核心公式如下:
Error Budget = 1 - SLO_target
例如:SLO_target = 99.9% (0.999)
Error Budget = 1 - 0.999 = 0.001 (即0.1%的请求允许失败)
在时间窗口内,误差预算的消耗量计算为:
Budget_consumed = (total_errors / total_requests) * 100%
剩余预算 = Error Budget - Budget_consumed
时间窗口的选择直接影响预算的敏感度:
- 滚动窗口(Rolling Window):最常用,例如过去30天或7天的滑动窗口。优点是与SLO定义一致,缺点是计算复杂度较高。
- 固定日历窗口(Calendar Window):按月或按季度重置预算。优点是易于理解,缺点是月末可能出现预算突增。
- 混合窗口:同时维护短期(1小时)和长期(30天)预算,用于不同告警场景。
以下是一个基于PromQL的误差预算实时计算公式示例:
# 定义SLO目标为99.9%
slo_target = 0.999
# 计算过去30天的总请求数和错误数
total_requests = sum(rate(http_requests_total[30d]))
total_errors = sum(rate(http_requests_total{status=~"5.."}[30d]))
# 计算错误率
error_rate = total_errors / total_requests
# 计算剩余误差预算
remaining_budget = (slo_target - error_rate) / (1 - slo_target) * 100
# 输出结果:剩余预算百分比,负数表示已超支
常见陷阱:不要将误差预算与可用性百分比直接混淆。误差预算是一个值(如0.1%),而可用性是相对值(如99.9%)。在台账中必须明确标注两者的单位,避免计算错误。
3.3 台账数据结构设计
误差预算台账需要存储历史快照、实时消耗和趋势数据,以便故障排查时快速回溯。推荐采用时序数据库 + 关系型元数据的混合存储方案。以下是一个标准台账表结构设计:
| 字段名 | 类型 | 说明 | 示例值 |
|---|---|---|---|
service_name |
String | 服务唯一标识 | api-gateway |
slo_target |
Float | SLO目标值(小数) | 0.999 |
window_days |
Int | 滚动窗口天数 | 30 |
total_requests |
BigInt | 窗口内总请求数 | 12500000 |
total_errors |
BigInt | 窗口内总错误数 | 12500 |
error_rate |
Float | 当前错误率 | 0.001 |
budget_remaining |
Float | 剩余预算百分比 | 0.0 |
budget_status |
Enum | 预算状态:OK/WARNING/EXHAUSTED | EXHAUSTED |
recorded_at |
Timestamp | 记录时间戳 | 2025-03-15T10:30:00Z |
在Prometheus中,台账数据通常以Gauge类型存储,便于后续告警和可视化:
# HELP error_budget_remaining 剩余误差预算百分比
# TYPE error_budget_remaining gauge
error_budget_remaining{service="api-gateway",slo="0.999",window="30d"} 0.0
# HELP error_budget_consumed_rate 误差预算消耗速率(每秒)
# TYPE error_budget_consumed_rate gauge
error_budget_consumed_rate{service="api-gateway"} 0.0000032
3.4 台账数据采集链路架构
下图展示了从Exporter采集到台账存储的完整链路,以及各环节的数据流:
链路故障排查要点:在Exporter采集链路中,最常见的故障点包括:(1) Exporter进程崩溃导致指标断流;(2) Prometheus与Exporter之间的网络超时;(3) 指标标签基数过高导致存储压力;(4) 台账计算引擎中的PromQL查询超时。建议在每个环节都设置独立的健康检查探针,并在台账中记录每次采集的延迟和错误率。
3.5 台账数据质量校验规则
为确保误差预算台账的准确性,必须建立数据质量校验机制。以下是一组推荐的校验规则:
- 连续性校验:检查时间序列是否存在超过2个采集周期的断点,断点超过阈值则标记为数据缺失。
- 范围校验:错误率必须在0~1之间,剩余预算必须在-100%~100%之间,超出范围立即告警。
- 一致性校验:总请求数 = 成功请求数 + 错误请求数,若不等则说明Exporter存在计数遗漏。
- 趋势校验:预算消耗速率不应在短时间内出现超过3倍标准差的变化,否则可能是指标采集异常。
以下是一个基于Python的台账数据校验伪代码示例:
def validate_error_budget_record(record):
errors = []
# 连续性校验
if record.time_gap > 120: # 超过2分钟断点
errors.append("数据采集断点超过2分钟")
# 范围校验
if not (0 <= record.error_rate <= 1):
errors.append(f"错误率异常: {record.error_rate}")
if not (-100 <= record.budget_remaining <= 100):
errors.append(f"剩余预算异常: {record.budget_remaining}%")
# 一致性校验
if record.total_requests != (record.success_count + record.error_count):
errors.append("请求计数不一致")
return errors
台账维护最佳实践:建议将校验规则直接集成到Exporter的指标输出中,例如在Prometheus中暴露一个
error_budget_data_quality 指标,值为0表示数据正常,值为1表示存在校验异常。这样可以在Grafana中直接监控台账的健康状态。