3. 误差预算台账设计:数据结构、字段定义与存储选型
误差预算台账是 SRE 可观测性体系中的核心数据资产,它将抽象的 SLO 承诺转化为可量化、可审计的预算消耗记录。本章聚焦台账的数据结构设计、关键字段定义以及存储选型,为后续的资源配置与调优提供数据基础。
3.1 台账数据结构设计
误差预算台账本质上是一个时序事件流,每条记录对应一个时间窗口内的预算消耗快照。我们采用扁平化的宽表结构,以平衡查询性能与存储成本。
| 字段分组 | 字段名 | 类型 | 说明 |
|---|---|---|---|
| 标识 | service_name |
string | 服务唯一标识,如 payment-api |
slo_name |
string | SLO 名称,如 latency-p99-200ms |
|
window_id |
uint64 | 时间窗口起始 Unix 时间戳(秒) | |
| 时间窗口 | window_duration |
string | 窗口长度,如 30d、7d、1h |
window_start |
timestamp | 窗口开始时间 | |
window_end |
timestamp | 窗口结束时间 | |
| 消耗率 | total_events |
uint64 | 窗口内总事件数 |
bad_events |
uint64 | 窗口内不良事件数(违反 SLO) | |
burn_rate |
float | 消耗率 = bad_events / total_events,单位 % | |
| 剩余预算 | error_budget_total |
float | 总误差预算(基于 SLO 目标计算) |
error_budget_consumed |
float | 已消耗预算 | |
error_budget_remaining |
float | 剩余预算 = total - consumed | |
| 元数据 | labels |
map | 可扩展标签,如 cluster、version |
updated_at |
timestamp | 记录最后更新时间 |
设计要点: 将
window_id 设为窗口起始时间戳,便于按时间范围快速聚合。消耗率与剩余预算分开存储,避免每次查询都重新计算。
3.2 核心字段定义详解
3.2.1 时间窗口(Time Window)
时间窗口是误差预算计算的基本单元。常见的窗口策略包括:
- 固定窗口: 30 天滑动窗口,每天滚动一次,适用于月度 SLO 审计。
- 滚动窗口: 7 天连续滚动,每小时更新一次,适用于实时告警。
- 复合窗口: 同时维护多个窗口(如 1h、7d、30d),用于多速率告警规则。
3.2.2 消耗率(Burn Rate)
消耗率衡量预算消耗的速度,是触发告警的关键指标。计算公式为:
burn_rate = (bad_events / total_events) / (1 - slo_target)
例如,SLO 目标为 99.9%,实际错误率为 0.2%,则消耗率为 0.2% / 0.1% = 2.0。消耗率 > 1 表示预算消耗速度超过预期。
3.2.3 剩余预算(Remaining Budget)
剩余预算直接反映服务的健康度。当剩余预算接近 0 时,需要立即采取行动。我们定义三个阈值区间:
| 剩余预算比例 | 状态 | 建议动作 |
|---|---|---|
| > 50% | 健康 | 常规监控 |
| 10% – 50% | 警告 | 排查异常消耗源 |
| < 10% | 危险 | 立即降级或回滚 |
3.3 台账存储选型:Prometheus vs. Thanos
误差预算台账需要长期存储(至少 30 天)并支持高效查询。Prometheus 和 Thanos 是 Kubernetes 生态中最主流的时序数据库方案。以下从台账场景对比两者:
| 维度 | Prometheus | Thanos |
|---|---|---|
| 存储容量 | 单节点有限,受磁盘和内存限制 | 对象存储(S3/GCS)无限扩展 |
| 数据保留 | 默认 15 天,可配置但增加运维成本 | 按需配置,支持永久保留 |
| 全局视图 | 单集群,跨集群需联邦 | 原生多集群聚合查询 |
| 查询性能 | 本地查询快,但大范围查询慢 | 通过 Store Gateway 加速历史查询 |
| 运维复杂度 | 低,开箱即用 | 中,需部署 Sidecar/Store/Compactor |
| 适用场景 | 单集群、短窗口(7d 内)台账 | 多集群、长窗口(30d+)台账 |
推荐选型: 对于生产级误差预算台账,建议采用 Thanos 作为存储后端。其对象存储能力可以低成本保留 30 天以上的历史数据,支持跨集群的全局预算视图,且通过 Compactor 组件实现数据降采样,进一步优化查询性能。
3.4 台账数据流架构
下图展示了误差预算台账从采集到存储的完整数据流,以及 Prometheus 与 Thanos 的分工边界。
3.5 台账存储配置示例
以下是一个基于 Thanos 的误差预算台账存储配置片段,使用 Prometheus Operator 的 Prometheus CRD 和 Thanos Sidecar:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: k8s-sre
spec:
retention: 15d
thanos:
version: v0.34.1
objectStorageConfig:
key: thanos.yaml
name: thanos-objectstorage
additionalScrapeConfigs:
name: additional-scrape-configs
key: prometheus-additional.yaml
---
apiVersion: v1
kind: Secret
metadata:
name: thanos-objectstorage
type: Opaque
stringData:
thanos.yaml: |
type: S3
config:
bucket: "sre-error-budget"
endpoint: "s3.amazonaws.com"
region: "us-east-1"
access_key: "AKIA..."
secret_key: "..."
insecure: false
signature_version2: false
注意: 对象存储的访问密钥应通过 Kubernetes Secret 管理,避免明文暴露。Thanos Compactor 组件需要定期运行以执行数据降采样和压缩,建议设置 2h 的降采样周期以平衡存储与查询性能。
3.6 台账查询最佳实践
基于上述数据结构,以下是一些常用的 PromQL 查询示例:
- 查询当前剩余预算:
error_budget_remaining{service_name="payment-api", slo_name="latency-p99-200ms"}
- 查询过去 1 小时消耗率:
rate(error_budget_consumed[1h]) / rate(error_budget_total[1h])
- 多窗口消耗率告警(基于多窗口多速率):
# 1 小时窗口消耗率 > 2 倍
rate(error_budget_consumed[1h]) / rate(error_budget_total[1h]) > 2
# 5 分钟窗口消耗率 > 10 倍(快速燃烧)
rate(error_budget_consumed[5m]) / rate(error_budget_total[5m]) > 10
优化建议: 在 Thanos 中,对于超过 30 天的历史数据,建议使用降采样数据(5m 分辨率)进行趋势分析,而非原始数据(15s 分辨率),以降低查询延迟和存储成本。