Prometheus

55708
下载
Prometheus 是一个开源的监控和告警系统,专注于时间序列数据的采集与存储。由 SoundCloud 开发,配备高级查询语言PromQL,便于数据挖掘与分析,并无缝对接多种可视化平台。

Histogram 和 Summary


Histogram 和 Summary 是更复杂的指标类型。而且单个 Histogram 或 Summary 会创建大量的时间序列,使得正确地使用这些指标类型更加困难。本节将帮助你选择并配置适用于特定用例适当的指标类型。

库支持

首先,请检查代码库库对 HistogramSummary 的支持。

一些库仅支持其中一种类型,或者它们只以有限的方式支持 Summary(缺乏 quantiles 支持)。

观察的数量与总和

Histogram 和 Summary 都会采样观察值,这通常是请求持续时间和响应大小。它们跟踪观察的_数量_和观察值的_总和_,允许你快速计算观察值的平均值。请注意,显示在 Prometheus 中的带有 _count 后缀的时间序列本质上是 Counter(如上所述,它只会增加)。带有 _sum 后缀的时间序列行为类似于 Counter,只要没有负观察值。显然,请求持续时间和响应大小永远不会是负数。原则上,你可以使用 Histogram 和 Summary 来观察负值(例如,摄氏温度)。在这种情况下,观察值的总和可以下降,所以你无法再在时间序列上应用 rate() 函数。在需要应用 rate() 并且无法避免负观察值的极少数情况下,你可以使用两个单独的 Summary,一个用于正观察值,另一个用于负观察值(后者带相反的符号),并在稍后的合适 Prometheus 表达式中结合结果。

要从名为 http_request_duration_seconds 的 Histogram 或 Summary 中计算过去 5 分钟内的平均请求持续时间,可以使用以下表达式:

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

Apdex 得分

Histogram 最直接的使用方法是统计特定观察值范围内的观察次数。

假设你有一个服务级别指标(SLO),要求 95% 的请求在 300 毫秒内完成。在这种情况下,可以配置一个 Histogram,其上限为 0.3 秒的桶,使用表达式计算 300 毫秒内处理完成的请求比例,当结果值低于 0.95 时发出警报。通过使用 histogram_quantile() 函数,可以为每个作业在过去 5 分钟内计算 http_request_duration_seconds 的 Apdex 得分:

(
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)

注意我们将两个桶的总和除以 2。原因在于 Histogram 桶是累积的le="0.3" 桶也包含在 le="1.2" 桶中;除以 2 可以纠正这一情况。

此计算不一定完全符合传统 Apdex 得分,因为它在计算满意部分和可容忍部分时存在误差。

分位数(Quantiles)

你可以使用 Histogram 和 Summary 计算所谓的 φ-分位数,其中 0 ≤ φ ≤ 1。φ-分位数是排名在 N 观察值中第 φ*N 的观察值。例如:φ=0.5 分位数被称为中位数。φ=0.95 分位数是第 95 百分位数。

Histogram 和 Summary 之间的主要区别在于:Summary 在客户端侧上计算流式 φ-分位数,并直接暴露这些值;而 Histogram 在服务器端上基于桶中的观察计数使用 histogram_quantile() 函数计算分位数,。

两种方法具有不同的含义:

HistogramSummary
必需的配置为预期的观察值范围选择合适的桶。选择所需的 φ-分位数和滑动窗口。其他 φ-分位数和滑动窗口无法在之后计算。
客户端性能观察成本非常低,只需递增 Counter 即可。观察成本昂贵,因为需要进行流式分位数计算。
服务器性能服务器必须计算分位数。应使用记录规则(recording rules)应对临时计算耗时过长的情况(例如,在大型仪表盘中)。服务器端成本低。
额外的时间序列数量每个配置的存储桶有一个时间序列。每个配置的分位数有一个时间序列。
φ-量化误差(参见下文了解详情)误差受相关观察上存储桶宽度维度的限制.误差受限于 φ 维度,由可配置的值限制。
φ-分位数和滑动时间窗口的指定Prometheus 表达式由客户端预先配置。
聚合Prometheus 表达式通常不可聚合

请注意表格中最后一项的重要性。让我们回到以下 SLO:在 300 毫秒内完成 95% 的请求。这次,你不希望显示请求在 300 毫秒内完成的比例,而是 95% 请求的请求持续时间,即 95% 的请求在多长的时间内完成。要这样做,你可以配置一个分位数为 0.95 的 Summary,并且例如使用 5 分钟的衰减时间,或者你可以配置一个Histogram,桶的配置围绕 300 毫秒,例如 {le="0.1"}{le="0.2"}{le="0.3"}{le="0.45"}。如果你的服务有多个实例副本,则你会收集来自所有实例的请求持续时间,并将其聚合为总体 95% 请求。然而,从一个 Summary 聚合预计算的分位数很少是有意义的。在这种特定情况下,平均分位数会产生统计上不合理的值。

avg(http_request_duration_seconds{quantile="0.95"}) // BAD!

使用 Histogram,聚合可以通过 histogram_quantile() 函数完美地实现。

histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le)) // GOOD.

此外,如果你的 SLO 发生变化并想绘制 90% 的百分位数,或者想考虑过去 10 分钟而不是过去的 5 分钟,你只需要调整上述表达式,而不必重新配置客户端。

分位数估算的误差

无论是在客户端还是服务器端计算,分位数都是估算的,理解这种估算的误差很重要。

以上面提到的 Histogram 示例为例,想象一下你的常规请求持续时间几乎全都在220毫秒左右,换句话说,如果你可以绘制“真实”的 Histogram,你会看到一个非常尖锐的峰值在220毫秒处。在上文中的 Prometheus Histogram 指标配置中,几乎所有观测结果,以及产生的第95百分位数,都将落入标有{le="0.3"}的桶中,即从200毫秒到300毫秒的桶。Histogram 可以确保真实的第95百分位数在200毫秒和300毫秒之间。为了返回一个单一值(而不是区间),它应用线性插值,在这种情况下给出了295毫秒的结果。分位数结果可能会让你觉得违反了 SLO 的要求,但实际上,第95百分位数略高于220毫秒,与 SLO 保持着还可以接受的差距。

实验的下一步:后端路由更改,向所有请求持续时间添加了固定的100毫秒。现在,请求持续时间有一个非常尖锐的峰值在320毫秒,并且几乎所有的观测结果都将落入从300毫秒到450毫秒的桶。第95百分位数被计算为442.5毫秒,尽管正确的值接近于320毫秒。虽然你只略微偏离了 SLO,但计算得出的第95分位数结果看起来要糟糕得多。

在上述的两种情况下,如果在客户端侧使用适当的算法(例如 Go 客户端使用的方法),Summary 都能够计算出准确的分位数。不幸的是,如果你需要聚合来自多个实例的观察结果时,无法使用 Summary。

幸运的是,由于你正确选择了桶边界,即使在这个人为的例子中分布观察值的峰值非常尖锐,Histogram 仍然能够准确地识别是否在或超出你的 SLO。此外,实际值与我们真正最感兴趣的值越接近(或者说,我们真正关心的值),计算出的值就越准确。

现在让我们再修改一次实验。在新的实验中,请求持续时间的分布有一个在150毫秒处的峰值,但没有那么尖锐,并且只占了90%的观察结果,剩下的10%的观察结果均匀分布在150毫秒到450毫秒之间的长尾中。在这种分布下,第95百分位数恰好与我们的SLO的300毫秒相匹配。此时使用 Histogram,计算出的值是准确的,因为第95百分位数恰好与一个桶边界相匹配。即使略有不同的值也会保持准确,因为相关桶内的(人为构造的)均匀分布正是桶内线性插值的预设前提。

现在,由 Summary 报告的分位数误差就变得有趣起来了。在 Summary 中分位数的误差是在φ的维度上配置的。在我们的例子中,我们可能已经配置了0.95±0.01,即计算出的值将在第94百分位数和第96百分位数之间。根据上述分布,第94百分位数是270毫秒,第96百分位数是330毫秒。由 Summary 给出的第95百分位数计算值可以在270毫秒到330毫秒之间的区间内任意位置,不幸的是,这正是在 SLO 内与明确超出 SLO 的区别所在。

简而言之:如果你使用 Summary,你可以控制在φ维度上的误差。如果你使用 Histogram,则可以通过选择合适的桶布局来控制在观测值维度上的误差。对于广泛的分布,φ的小变化会导致观测值的大偏差。对于尖锐分布,观察值的一个小区间则覆盖了φ的大区间。

两条经验法则:

  1. 如果你需要聚合,选择 Histogram。
  2. 否则,如果你对将被观察到的值的范围和分布有所了解,请选择 Summary。另外,如果你需要准确的分位数,无论值的范围和分布如何,请选择 Summary。

如果我的客户端库不支持我需要的指标类型,我可以做些什么?

你可以实现它,Prometheus 欢迎代码贡献!通常情况下,我们预估 Histogram 比 Summary 更为迫切需要。Histogram 在客户端库中实现起来也相对更容易,因此我们建议如果你不确定,可以优先实现 Histogram。

该文档基于 Prometheus 官方文档翻译而成。


observability.cn Authors 2024 | Documentation Distributed under CC-BY-4.0
Copyright © 2017-2024, Alibaba. All rights reserved. Alibaba has registered trademarks and uses trademarks.
浙ICP备2021005855号-32