2. Metric 数据类型详解:定义与适用场景

在可观测性工程中,选择正确的 Metric 数据类型是构建精准告警阈值的基础。Prometheus 定义了四种核心 Metric 类型:Counter、Gauge、Histogram 和 Summary。每种类型对应不同的数据特征与查询模式,错误的选择会导致告警失真或性能浪费。

核心原则: 数据类型决定了指标的可聚合性、统计语义以及告警表达式的写法。在定义 SLO 和告警规则前,必须为每个观测指标匹配正确的数据类型。

2.1 Counter(计数器)

定义: Counter 是一种只增不减的累计值,仅在系统重启或重置时归零。它用于记录事件发生的次数或累计量。

核心特征:

  • 单调递增: 值只能增加或归零(重启),不能减少。
  • 原子操作: 适合高并发场景下的计数。
  • 衍生计算: 原始值本身意义有限,通常通过 rate()、increase() 函数计算变化率。

适用场景:

场景 示例 Metric 告警表达式
HTTP 请求总数 http_requests_total rate(http_requests_total[5m]) > 1000
错误次数 errors_total rate(errors_total[5m]) > 10
任务执行次数 job_executions_total increase(job_executions_total[1h]) == 0
网络字节流入量 network_bytes_received_total rate(network_bytes_received_total[1m]) > 1e9
避坑提示: 不要用 Counter 直接设置阈值告警(如 errors_total > 100),因为累计值会随时间无限增长,导致告警永远触发。必须使用 rate() 或 increase() 转换为速率。

2.2 Gauge(仪表盘)

定义: Gauge 表示一个可上下波动的瞬时值,反映系统的当前状态。它是最直观的指标类型。

核心特征:

  • 可增可减: 值可以任意变化,没有单调性约束。
  • 快照语义: 直接反映采样时刻的数值,无需速率转换。
  • 适合阈值告警: 原始值可直接用于比较。

适用场景:

场景 示例 Metric 告警表达式
CPU 使用率 cpu_usage_percent cpu_usage_percent > 90
内存使用量 memory_used_bytes memory_used_bytes > 8e9
队列深度 queue_depth queue_depth > 1000
连接数 active_connections active_connections > 5000
最佳实践: Gauge 适合与 avg_over_time()、max_over_time() 等聚合函数配合,消除瞬时抖动,生成更稳定的告警阈值。

2.3 Histogram(直方图)

定义: Histogram 将观测值(如请求延迟)分配到预定义的桶(bucket)中,同时记录所有观测值的总和与总数。它用于分析数据的分布特征。

核心特征:

  • 分桶统计: 每个桶记录落在该区间内的观测次数。
  • 可计算分位数: 通过 histogram_quantile() 函数估算 P50、P90、P99 等。
  • 可聚合: 多个 Histogram 可以合并计算全局分位数。

适用场景:

场景 示例 Metric 告警表达式
请求延迟分布 http_request_duration_seconds histogram_quantile(0.99, rate(...)) > 0.5
响应大小分布 http_response_size_bytes histogram_quantile(0.95, rate(...)) > 1e6
数据库查询耗时 db_query_duration_seconds histogram_quantile(0.9, rate(...)) > 2
告警优势: Histogram 能发现“大多数请求正常,但少数请求极慢”的尾部延迟问题,这是平均值告警无法捕获的。

2.4 Summary(摘要)

定义: Summary 在客户端直接计算分位数,并将结果暴露为预定义的分位数(如 P50、P90、P99)以及观测总数和总和。

核心特征:

  • 客户端计算: 分位数在应用端算好,服务端直接读取。
  • 固定分位数: 分位数在定义时指定,无法动态查询其他分位。
  • 不可聚合: 多个 Summary 的分位数不能合并计算全局分位。

适用场景:

场景 示例 Metric 告警表达式
已知分位数的延迟监控 rpc_duration_seconds rpc_duration_seconds{quantile="0.99"} > 1
预计算性能指标 api_latency_milliseconds api_latency_milliseconds{quantile="0.95"} > 200
关键限制: Summary 的分位数无法跨实例聚合。如果你需要全局 P99,必须使用 Histogram。Summary 更适合单实例的精确分位需求。

2.5 四种类型对比总览

特性 Counter Gauge Histogram Summary
值变化方向 只增不减 可增可减 累计计数 累计计数
原始值可用性 低(需 rate) 高(直接使用) 中(需分桶计算) 中(直接读分位)
分位数支持 不支持 不支持 支持(服务端计算) 支持(客户端计算)
跨实例聚合 支持 支持 支持 不支持
典型告警方式 速率阈值 值阈值 分位数阈值 分位数阈值
存储开销 低 低 高(桶数相关) 中

2.6 数据类型选择决策流程

Metric 数据类型选择决策流程 观测指标 是否只增不减? Counter 否 是 是否反映瞬时状态? Gauge 否 是否需要分位数? Histogram 否 Summary 提示:Histogram 支持跨实例聚合,Summary 不支持;优先选择 Histogram 用于全局告警

2.7 告警阈值设计中的类型选择建议

  • 速率类告警(如 QPS 突增): 使用 Counter + rate(),设置每秒或每分钟的速率阈值。
  • 饱和度类告警(如 CPU 高): 使用 Gauge,设置百分比或值的上下限。
  • 尾部延迟告警(如 P99 超时): 使用 Histogram,通过 histogram_quantile() 设置分位数阈值。
  • 预知分位需求(如固定 P95 监控): 使用 Summary,但注意无法聚合多实例。
实战建议: 在微服务架构中,推荐统一使用 Histogram 记录延迟,以便在全局维度聚合计算 SLO。仅在明确不需要跨实例聚合且对性能有极致要求时,才考虑 Summary。