2. Metric 数据类型详解:Counter、Gauge、Histogram、Summary 的定义与适用场景
在可观测性体系中,Metric(指标)是量化系统状态与行为的基础。Prometheus 及其兼容生态定义了四种核心指标类型:Counter(计数器)、Gauge(仪表盘)、Histogram(直方图)、Summary(摘要)。理解每种类型的数学特性、存储模型与适用边界,是设计可靠告警规则与降噪策略的前提。
2.1 四种 Metric 类型总览
| 类型 | 值语义 | 可增减 | 典型聚合方式 | 适用场景 |
|---|---|---|---|---|
| Counter | 单调递增 | 仅增加 | rate() / increase() | 请求总数、错误计数、任务完成数 |
| Gauge | 任意瞬时值 | 可增可减 | avg() / max() / min() | CPU 使用率、内存占用、并发连接数 |
| Histogram | 分桶计数 + 总和 | 仅增加 | histogram_quantile() | 请求延迟分布、响应大小分布 |
| Summary | 预计算分位数 + 总和 | 仅增加 | 直接读取分位数 | SLA 延迟分位数、客户端侧分位统计 |
设计要点:Counter 与 Gauge 是“单值”指标,Histogram 与 Summary 是“多值”指标。告警降噪时,Counter 必须配合速率函数使用,直接对原始值设阈会导致误报或漏报。
2.2 Counter(计数器)—— 只增不减的累积量
定义:Counter 是一种单调递增的累积计数器,其值在进程生命周期内只允许增加(或重置为零)。典型场景包括 HTTP 请求总数、数据库查询次数、任务执行成功数。
核心特性:
- 值只能增加,不能减少(进程重启时重置为 0)。
- 原始值本身无意义,必须通过
rate()或increase()计算每秒速率或增量。 - 适用于衡量“事件发生的频率”或“总量趋势”。
告警降噪注意点:
- ❌ 错误做法:对 Counter 原始值设置固定阈值(如
errors_total > 100),会导致重启后误报。 - ✅ 正确做法:使用
rate(errors_total[5m]) > 0.1检测错误率突增。
# 示例:PromQL 查询最近 5 分钟的错误率
rate(http_requests_total{status="500"}[5m])
2.3 Gauge(仪表盘)—— 可升可降的瞬时快照
定义:Gauge 表示一个可任意变化的瞬时值,反映系统当前状态。典型场景包括 CPU 使用率、内存占用量、活跃连接数、队列深度。
核心特性:
- 值可增可减,反映当前快照。
- 原始值可直接用于告警,无需速率转换。
- 适合使用
avg()、max()、min()等聚合函数。
告警降噪注意点:
- Gauge 对瞬时抖动敏感,建议配合
avg_over_time()或max_over_time()做窗口平滑。 - 避免对高频抖动指标使用单点阈值,容易产生告警风暴。
# 示例:检测 CPU 使用率超过 90% 持续 5 分钟
avg_over_time(node_cpu_seconds_total{mode="idle"}[5m]) < 0.1
常见误区:不要将 Gauge 用于“累计计数”场景,例如用 Gauge 记录请求总数。进程重启后 Gauge 会丢失历史累积值,而 Counter 可以正确从 0 重新开始。
2.4 Histogram(直方图)—— 分布感知的分桶统计
定义:Histogram 将观测值(如请求延迟)分配到预定义的桶(bucket)中,同时记录所有观测值的总和与计数。它不存储原始数据,而是存储分桶计数。
核心特性:
- 每个桶是一个 Counter,记录落在该桶范围内的观测次数。
- 额外提供
_sum(总和)和_count(总数)。 - 通过
histogram_quantile()函数在服务端计算分位数。
适用场景:
- 请求延迟分布(P50、P95、P99)。
- 响应大小分布。
- 需要灵活调整分位数计算精度的场景。
# 示例:计算 P99 延迟(单位:秒)
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
告警降噪注意点:
- 桶边界设计直接影响分位数精度,桶太稀疏会导致分位数跳跃。
- 建议覆盖预期值的 95% 范围,并在尾部增加细粒度桶。
2.5 Summary(摘要)—— 客户端预计算的分位数
定义:Summary 在客户端直接计算分位数,并将预计算的分位数、总和、计数一起暴露给监控系统。与 Histogram 不同,Summary 不暴露桶计数,而是直接暴露分位数值。
核心特性:
- 分位数在客户端计算,服务端直接读取。
- 无法跨进程聚合分位数(因为预计算的分位数不可合并)。
- 适合已知分位数需求且客户端计算资源充足的场景。
适用场景:
- SLA 报告中的固定分位数(如 P99)。
- 客户端侧需要精确分位数,且不依赖服务端聚合。
# 示例:Summary 暴露的指标(Prometheus 格式)
# HELP rpc_duration_seconds Summary of RPC duration
# TYPE rpc_duration_seconds summary
rpc_duration_seconds{quantile="0.5"} 0.052
rpc_duration_seconds{quantile="0.9"} 0.1
rpc_duration_seconds{quantile="0.99"} 0.2
rpc_duration_seconds_sum 1234.56
rpc_duration_seconds_count 10000
Histogram vs Summary 选择指南:
- 需要灵活调整分位数或跨服务聚合 → 选 Histogram。
- 已知固定分位数、客户端计算资源充足、无需聚合 → 选 Summary。
- 需要精确分位数且数据量极大 → 优先考虑 Summary 减少服务端计算压力。
2.6 四种类型的聚合特性对比
2.7 选型决策流程
- 判断值是否单调递增:是 → Counter;否 → 进入下一步。
- 判断是否需要分布信息:否 → Gauge;是 → 进入下一步。
- 判断是否需要灵活分位数或跨进程聚合:是 → Histogram;否 → Summary。
实战建议:在微服务架构中,优先使用 Histogram 暴露延迟指标,便于统一在 Prometheus 端计算 P99 并做告警降噪。Summary 更适合 SDK 侧已有固定分位数需求的场景,如 gRPC 客户端延迟统计。