Prometheus直方图(Histograms)与摘要(Summaries)使用指南

本文档来自 Prometheus 官方文档 - Histograms and summaries,旨在帮助用户在直方图(Histogram)和摘要(Summary)之间做出合理选择,并正确配置和使用它们。

⚠️ 注意:本文档撰写于 原生直方图(Native Histograms) 成为稳定功能之前(该特性自 v2.40 起实验性引入),未来内容将更新以涵盖新特性。


一、核心概念

  • Histogram 和 Summary 都用于采样观测值(如请求延迟、响应大小)。

  • 两者均自动暴露:

    • _count:观测次数(本质是 Counter)
    • _sum:观测值总和(通常也是 Counter,除非观测值可为负)
  • 可通过以下表达式计算平均值(过去 5 分钟):

    1
    rate(http_request_duration_seconds_sum[5m]) / rate(http_request_duration_seconds_count[5m])

二、Histogram vs Summary:关键区别

特性 直方图(Histogram) 摘要(Summary)
配置方式 在服务端配置桶(buckets)边界 在客户端预设 φ-分位数(如 0.95)和滑动窗口
客户端开销 极低(仅递增计数器) 较高(需实时计算分位数)
服务端开销 较高(需用 histogram_quantile() 计算分位数) 极低(分位数已由客户端计算好)
时间序列数量 每个桶一个 + _sum + _count 每个预设分位数一个 + _sum + _count
分位数误差 由桶宽决定(观测值维度) 由 ε 决定(φ 维度,如 ±0.01)
查询灵活性 支持任意分位数、任意时间窗口(通过 PromQL) 仅支持预设的分位数和窗口
聚合能力 ✅ 支持跨实例聚合(推荐!) 不可聚合(平均分位数无统计意义)

三、何时使用 Histogram?

强烈推荐在以下场景使用 Histogram:

  1. 需要跨多个实例聚合指标(如微服务集群)

    1
    histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
  2. 不确定未来需要哪些分位数或时间窗口

  3. 希望降低客户端资源消耗

  4. 能合理预估观测值的分布范围,从而设置合适的桶

💡 示例:SLO 要求 95% 请求 < 300ms
可直接用 Histogram 桶计算达标率:

1
2
3
sum(rate(http_request_duration_seconds_bucket{le="0.3"}[5m])) by (job)
/
sum(rate(http_request_duration_seconds_count[5m])) by (job)

四、何时使用 Summary?

仅在以下情况考虑 Summary:

  1. 单实例应用(无需聚合)
  2. 对特定分位数精度要求极高,且分布未知或变化剧烈
  3. 无法预知合理的桶边界

⚠️ 警告:

1
avg(http_request_duration_seconds{quantile="0.95"}) // 错误!不可聚合!

五、分位数估算误差分析

Histogram 的误差

  • 误差取决于桶的宽度
  • 例:若 95% 请求集中在 220ms,但桶为 [0.2, 0.3),则估算值可能为 295ms(线性插值),看似接近 SLO 实则远优于。
  • 优点:即使估算不准,仍能正确判断是否违反 SLO(只要桶边界覆盖 SLO 阈值)。

Summary 的误差

  • 误差在 φ 维度(如配置为 0.95±0.01,则实际在 94%~96% 分位之间)。
  • 若分布有长尾,94% 与 96% 对应的实际延迟可能相差巨大(如 270ms vs 330ms),导致无法准确判断是否违反 SLO。

六、Apdex 分数近似计算(使用 Histogram)

Apdex = (满意请求 + 可容忍请求/2) / 总请求
假设目标 300ms,容忍 1.2s:

1
2
3
4
5
6
7
(
sum(rate(http_request_duration_seconds_bucket{le="0.3"}[5m])) by (job)
+
sum(rate(http_request_duration_seconds_bucket{le="1.2"}[5m])) by (job)
) / 2
/
sum(rate(http_request_duration_seconds_count[5m])) by (job)

📝 注意:因桶是累积的,le="0.3" 已包含在 le="1.2" 中,故需除以 2 校正。


七、客户端库支持

  • 并非所有语言客户端都同时完整支持 Histogram 和 Summary。
  • 建议优先实现 Histogram:更易开发、更通用、支持聚合。

八、总结建议

  • 默认选择 Histogram:适用于绝大多数场景,尤其是分布式系统。
  • 避免使用 Summary,除非你明确知道它更适合你的单机高精度需求。
  • 合理设计桶边界:围绕 SLO 或关键阈值(如 0.1s, 0.2s, 0.3s, 0.5s, 1s, 2s…)。
  • 永远不要聚合 Summary 的分位数

🌟 黄金法则
要聚合 → 选 Histogram
不要聚合 + 要极致精度 → 才考虑 Summary