2. Metric Design 基础:四大黄金信号、标签设计原则与聚合降采样策略

在构建误差预算台账之前,必须掌握 Metric Design 的核心基础。本章聚焦三个关键领域:四大黄金信号(识别哪些指标值得建模)、标签设计原则(确保指标可被高效筛选与关联)、聚合与降采样策略(平衡存储成本与查询精度)。这些基础直接决定误差预算台账的数据结构是否健壮、可扩展且易于运维。

2.1 Metric 的四大黄金信号

并非所有数据点都适合作为 Metric 纳入误差预算台账。我们通过“四大黄金信号”来筛选高价值指标,确保每个 Metric 都能为 SLO 计算和故障定位提供明确信号。

黄金信号 核心问题 典型 Metric 示例 在误差预算中的角色
延迟 (Latency) 服务响应有多快? p50/p95/p99 请求延迟 定义“慢请求”是否消耗误差预算
流量 (Traffic) 系统承载多少负载? QPS、RPS、并发连接数 作为分母计算错误率,影响预算消耗速率
错误 (Errors) 请求失败的比例? HTTP 5xx 率、异常计数 直接消耗误差预算的核心信号
饱和度 (Saturation) 系统还有多少余量? CPU 使用率、内存占用、队列深度 预警即将发生的预算消耗激增
设计提示: 在误差预算台账中,延迟和错误通常是“消耗型”信号,直接计入不良事件;流量和饱和度是“上下文型”信号,用于解释预算消耗的根因和趋势。台账数据结构应区分这两类信号的存储粒度。
四大黄金信号与误差预算消耗关系 误差预算 (Error Budget) 延迟 (Latency) 流量 (Traffic) 错误 (Errors) 饱和度 (Saturation) 实线:直接消耗预算(延迟、错误) | 虚线:间接影响预算(流量、饱和度)

2.2 Metric 的标签设计原则

标签(Labels)是 Metric 的元数据,决定了我们能否在误差预算台账中按维度进行切片、钻取和聚合。糟糕的标签设计会导致基数爆炸、查询缓慢和预算计算错误。

2.2.1 标签设计五大原则

  1. 高基数标签隔离存储:将 user_id、request_id 等高基数标签放在日志或事件存储中,不要作为 Metric 标签。Metric 标签的基数建议控制在 10^4 以内。
  2. 业务语义优先:标签名应直接反映业务含义,如 service_name、deployment_environment、error_code_category,避免使用晦涩的内部编码。
  3. 层级扁平化:避免在标签中嵌入层级结构(如 region.az.host),应拆分为独立标签:region、availability_zone、host。
  4. 不可变标签与可变标签分离:service_name、metric_type 等不可变标签用于定义 Metric 身份;deployment_version、experiment_group 等可变标签用于分析。
  5. 避免冗余标签:如果一个标签的值可以由其他标签推导得出(如 full_hostname 包含 host 和 domain),则只保留最小集合。
案例: 一个设计良好的误差预算 Metric 标签集:
{service="checkout", slo_name="checkout_availability", window="30d", error_class="timeout"}
避免:{service="checkout", host="ip-10-0-1-23.ec2.internal", user_id="12345", request_path="/api/v1/checkout"}

2.2.2 标签设计对比

维度 推荐做法 反模式
基数控制 标签值数量 < 10,000 将用户 ID、Session ID 作为标签
命名规范 snake_case,如 error_code 混合大小写或使用空格
标签数量 每个 Metric 5~8 个标签 超过 15 个标签,导致存储膨胀
值格式 枚举值或短字符串 包含路径、JSON 或长文本
标签设计原则 → 误差预算台账数据结构 高基数隔离 业务语义优先 层级扁平化 不可变/可变分离 误差预算 Metric 结构 • metric_name (不可变) • service (不可变) • slo_window (不可变) • error_class (可变) • deployment_version (可变) • region (扁平化标签)

2.3 Metric 的聚合与降采样策略

误差预算台账需要同时支持高精度短期分析和低成本长期存储。聚合与降采样策略决定了如何在数据精度与存储/查询成本之间取得平衡。

2.3.1 聚合策略

聚合发生在数据写入时或查询时。对于误差预算,我们推荐以下分层聚合模型:

  • 原始数据(Raw):保留 1~7 天,用于详细根因分析。粒度:10 秒 ~ 1 分钟。
  • 滚动窗口聚合(Rolling Window):保留 30 天,用于 SLO 计算和预算消耗跟踪。粒度:1 分钟 ~ 5 分钟。聚合函数:sum(计数类)、avg(延迟类)、count(事件类)。
  • 长期降采样(Downsampled):保留 1 年以上,用于趋势分析和容量规划。粒度:1 小时 ~ 1 天。聚合函数:avg、p95、max。
注意: 降采样时,不要只保留平均值。对于误差预算,p95 和 max 延迟的降采样版本对于判断“最差情况”至关重要。建议至少保留 avg、p95、max 和 count 四个聚合值。

2.3.2 降采样策略对比

策略 方法 适用场景 存储节省 精度损失
Last 保留时间窗口内最后一个值 瞬时状态指标(如版本号) 高 高
Avg 计算窗口内算术平均 资源利用率、平均延迟 中 中
Min/Max 保留窗口内极值 饱和度告警、峰值延迟 中 中(丢失分布)
Percentile (p50/p95/p99) 使用 T-Digest 或 HDR Histogram 近似计算 误差预算 SLO 计算(推荐) 低 低(可控)
Counter Reset 对计数器进行速率转换后再降采样 QPS、错误率等速率指标 高 低(需正确处理重置)

2.3.3 误差预算台账的推荐降采样流水线

# 伪代码:误差预算 Metric 降采样配置
metric "http_request_duration_seconds" {
  # 原始数据:10s 粒度,保留 2 天
  raw {
    retention = "2d"
    resolution = "10s"
  }

  # 滚动窗口:1m 粒度,保留 30 天,用于 SLO 计算
  rolling_window {
    retention = "30d"
    resolution = "1m"
    aggregators = ["avg", "p95", "p99", "count"]
  }

  # 长期降采样:1h 粒度,保留 365 天,用于趋势分析
  long_term {
    retention = "365d"
    resolution = "1h"
    aggregators = ["avg", "p95", "max", "count"]
  }
}
关键设计决策: 在误差预算台账中,滚动窗口聚合是 SLO 计算的直接数据源。建议将滚动窗口的聚合结果存储在独立的 Metric 表中(如 slo_budget_consumption),与原始 Metric 表分离,以避免查询 SLO 时扫描大量原始数据。
误差预算 Metric 聚合与降采样分层架构 原始数据层 (Raw) — 10s 粒度 · 保留 2 天 存储所有标签维度,用于根因分析和调试 滚动窗口聚合层 (Rolling Window) — 1m 粒度 · 保留 30 天 聚合函数:avg, p95, p99, count · 用于 SLO 计算和预算消耗跟踪 长期降采样层 (Long-term) — 1h 粒度 · 保留 365 天 聚合函数:avg, p95, max, count · 用于趋势分析和容量规划 降采样时保留 p95 和 max,确保误差预算的“最差情况”可追溯