Prometheus 最佳实践 Summary 和 Histogram
本文分享自华为云社区《Prometheus最佳实践 Summary和Histogram》,作者:张俭。
前言
Histogram 和 Summary 都是复杂的指标,不仅仅是因为直方图和 summary 包含了多个时间序列,而且它们还较难使用正确。
观测中的 Count 和 Sum
Histo 和 summary 都是采样观测,典型的采样维度有 响应大小 和 请求时长 。它们跟踪观测值的数量和观测值的总和,从而使您可以计算观测值的平均值。 请注意,观察值的数量(在 Prometheus 中显示为带有“ _count”后缀的时间序列)本质上是一个计数器(如上所述,它只会增加)。 观测值的总和(以带有_sum 后缀的时间序列显示)也可以充当计数器,只要没有负面的观测值即可。 显然,请求持续时间或响应大小永远不会为负。 但是,原则上,您可以使用摘要和直方图来观察负值(例如,摄氏温度)。 在这种情况下,观察值的总和可能会下降,因此您无法再对其应用“ rate()”。
例如,在 Histo 或者 summary 上计算 5 分钟内的平均请求时长,使用如下的 PromQL
Apdex 分数
Histo(而不是 summary)的一个直接用途是对落入指定观察值桶中的观察值进行计数。
你可能会有诸如这样的 SLO:百分之 95 的请求都要在 300ms 内完成返回。在这个场景下,定义一个 Histo,定义一个桶的界限为 300ms。然后当这个桶的数量小于百分之 95 的时候就告警。
如下的表达式可以计算上文所述的 SLO
你可以以一种非常相似的方式估计 Apdex 分数。以请求时长为例,配置上界为目标请求时长,另一个桶配置为最大忍受时长(通常是目标请求时长的四倍)。例如目标请求时长为 300ms,最大忍受请求时长为 1.2s。如下的表达式计算了每 5 分钟的 Apdex 分数
注: Apdex 分数计算
请注意,我们将两个存储桶的总和相除。 原因是直方图存储桶是[累积](https://en.wikipedia.org/wiki/Histogram#Cumulative_histogram)。 le =“ 0.3”
存储桶也包含在le =“ 1.2”
存储桶中; 将其除以 2 即可解决此问题。
该计算与传统的 Apdex 分数不完全匹配,因为它包括计算中满意和可忍受的部分中的误差。
Quantiles 分位数
你可以使用 summary 和 histogram 来计算 φ-分位数,φ在 0 到 1 之间,左右都为闭区间。φ分位数是一个用来计算前φ界限的观测值。换句话说,就是大家平时讲的 pxx。p50 即是中位数。为了打字方便,后面用 分位数 来行文。
Summary 和 Histogram 的一个区分要点是 summary 在客户端侧计算分位数,然后直接暴露它们,然而 histogram 在客户端侧暴露桶的技术,然后在服务端侧使用 histogram_quantitle() 函数来计算分位数。
请注意表中最后一项的重要性。 让我们回到在 300 毫秒内处理 95%请求的 SLO。 这次,您不想显示 300 毫秒内已处理请求的百分比,而是显示第 95 个百分位数,即您为 95%的请求提供服务的请求持续时间。 为此,您可以配置 summary 为 0.95 位数,衰减时间为 5 分钟(例如),也可以配置直方图,并在 300ms 标记附近添加几个存储桶,例如 {le =“ 0.1”}
,{le =“ 0.2”}
,{le =“ 0.3”}
和{le =“ 0.45”}
。 如果您的服务使用多个实例进行复制运行,则将从其中的每个实例收集请求持续时间,然后将所有内容汇总到整体的 95%。 但是,从 summary 汇总预先计算的分位数很少是有意义的。 在这种特定情况下,平均分位数会产生统计上无意义的值。
使用 histograms,使用 histogram_quantile()
可以完全实现聚合。
此外,如果您的 SLO 发生变化并且您现在想要绘制第 90 个百分位,或者您想将最近 10 分钟而不是最近 5 分钟考虑在内,则只需调整上面的表达式即可,而无需重新配置客户端。
分位数估计的误差
分位数,无论是在客户端计算还是在服务端计算,都是一个估计值。理解分位数的误差对我们非常重要。
让我们从上面 histogram 的例子继续,想象你通常的请求时长基本上都是 220ms,或者换句话说,如果你绘制出了正确的 histogram,你将会在 220ms 处看到一个超级大的尖峰。在上面配置的 Prometheus 直方图度量标准中,几乎所有观察结果以及第 95 个百分位都将落入标有“ {le =“ 0.3”}”的存储桶中,即从 200ms 到 300ms 的存储桶。 直方图实现可确保真实的第 95 个百分位数在 200 毫秒至 300 毫秒之间。 要返回单个值(而不是间隔),它会应用线性插值,在这种情况下将产生 295ms。 计算得出的分位数给您的印象是您接近违反 SLO,但实际上,第 95 个百分位数略高于 220ms,这是与您的 SLO 相当舒适的距离。
我们的思想实验的下一步:更改后端路由会为所有请求持续时间增加固定的 100ms。 现在,请求持续时间在 320 毫秒处急剧增加,几乎所有观察结果都会从 300 毫秒下降到 450 毫秒。 尽管正确值接近 320ms,但第 95 个百分位数计算为 442.5ms。 虽然您仅在 SLO 之外,但计算得出的第 95 分位数看起来要差得多。
Summary 就没有上述的问题,除非它在客户端侧使用了估计算法。不幸的是,如果你想要在多个客户端之间聚合,那你无法使用 summary。
幸运的是,由于你合适的选择了桶的边界,即使在观测值的分布非常锋利的尖刺的这个人为的例子,直方图能够正确识别,如果你是内或您的 SLO 之外。同样,分位数的实际值越接近我们的 SLO(或换句话说,我们实际上最感兴趣的值),计算出的值就越准确。
现在让我们再次修改实验。在新的设置中,请求持续时间的分布在 150ms 处有一个尖峰,但不像以前那样尖锐,仅占观察值的 90%。 10%的观察结果平均分布在 150 毫秒至 450 毫秒之间的长尾巴中。根据这种分布,第 95 个百分位数恰好在我们的 300ms SLO 处。使用直方图,由于第 95 个百分位数的值恰好与铲斗边界之一重合,因此计算得出的值是准确的。甚至略有不同的值也将是准确的,因为相关存储区中的(人为)均匀分布正是存储区中线性插值所假定的。
摘要报告的分位数误差现在变得更加有趣。摘要中的分位数误差是在φ维度中配置的。在我们的情况下,我们可能配置为 0.95±0.01,即计算出的值将介于 94%和 96%之间。具有上述分布的第 94 位为 270ms,第 96 位为 330ms。摘要报告的第 95 个百分位数的计算值可以在 270ms 和 330ms 之间的任何位置,很遗憾,这是 SLO 内明显与 SLO 外明显之间的所有差异。
最重要的是:如果使用 summary,则可以通过调整维度 来控制误差。如果使用直方图,则可以控制 bucket 分配 来调整误差(通过选择适当的桶布局)。
分布较宽时,φ的微小变化会导致观测值的较大偏差。分布较锐利时,观测值的较小间隔将覆盖φ的较大间隔。也就是说,整体宽泛的时候,分位数一点点变化,都会导致分位值的较大变化。整体较紧凑的时候,很小的分位值差值,就能覆盖很大的分位数比例。
两条经验法则:
1.如果需要聚合,请选择 histogram。
2.否则,如果您对将要观察的值的范围和分布有所了解,请选择 histogram。无论值的范围和分布是什么,如果都需要准确的分位数,请选择 summary。
版权声明: 本文为 InfoQ 作者【华为云开发者联盟】的原创文章。
原文链接:【http://xie.infoq.cn/article/7e36220da4b600406a6b500ae】。文章转载请联系作者。
评论