直方图和摘要图

浏览 0      扫码          2019-12-09 21:49:23     码农文档      译文原文 英文原文

公告:如果您也想加入翻译队伍,或者您有相关中文文档想要贡献给大家,请联系coderdocument@163.com ,谢谢!

直方图和摘要图是更复杂的指标类型。一个直方图或摘要图不仅会创建大量时间序列,而且正确使用这些指标类型也更加困难。本节将帮助你选择和配置合适的指标类型。

库支持

首先,检查库对直方图摘要图的支持。

有些库只支持这两种类型中的一种,或者它们只以有限的方式支持摘要图(如:缺少分位数计算)。

观察计数和总和

直方图和摘要图都会对观察进行采样,典型的有请求持续时间或响应大小。它们跟踪观察值的数量和观察值的总和,这样就可以计算观察值的平均值。注意,观察值的数量(在Prometheus中显示为带有_count后缀的时间序列)本质上是一个计数器(如上所述,它只会增加)。观察值的和(以带有_sum后缀的时间序列的形式出现)也类似计数器,只是没有负数观察值即可。显然,请求持续时间或响应大小不可能为负数。然而,原则上,你可以使用摘要图和直方图来观察负数值(例如,摄氏温度)。在这种情况下,观察值的总和可能减小,因此不能再对其应用rate()函数。

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


   
       

Apdex评分

直方图(但不是摘要图)的一个直接用法是对落入特定桶的观测值进行计数。

你可能有一个SLO,可以在300毫秒内处理95%的请求。在这种情况下,配置一个直方图,使其桶的上限为0.3秒。然后,你可以直接配置,在300毫秒内服务的请求的相对数量,如果该值低于0.95,则很容易发出告警。下面的表达式通过作业计算最近5分钟内服务的请求。使用名为http_request_duration_seconds的直方图收集请求持续时间。


   
       

你可以用类似的方法来估算著名的Apdex评分。将一个桶(bucket)配置为目标请求持续时间的上限,另一个桶配置为能够容忍的请求持续时间(通常是目标请求持续时间的4倍)的上限。示例:目标请求持续时间为300ms。可容忍的请求持续时间为1.2秒。下面的表达式给出了过去5分钟内每个作业的Apdex评分:


   
       

注意,我们将两个桶求和后再除以2。原因是直方图桶是累积的le="0.3"的桶也包含在le="1.2"桶中;除以2就得到了正确值。

该计算与传统的Apdex评分不完全匹配,因为它包含了计算中可接受的错误。

分位数

你可以使用摘要图和直方图计算所谓的φ-quantiles,其中在0≤φ≤1。φ-quantile指在N个观测值中排名为φ*N的观察值。φ-quantiles的例子:0.5-quantile被称为中位数。0.95-quantile为第95百分位数。

摘要图和直方图的本质区别是,摘要图计算流φ-quantiles直接在客户端暴露,而直方图暴露桶中的观察计数和分位数发生在服务端(使用histogram_quantile()函数`))。

这两种指标类型有许多不同的含义:

直方图 摘要图
必需的配置 挑选适合于预期观察值范围的桶。 选择期望的φ-quantiles和滑动窗口。其它φ-quantiles和滑动窗口随后无法计算。
客户端性能 观察值非常廉价,因为它们只需要增加计数器。 由于流式分位数计算,观察代价很高。
服务端性能 服务端必须计算分位数。如果计算花费的时间太长(例如,在大型仪表盘中),可以使用记录规则 服务端成本低。
时间序列数量(包括_sum_count序列) 每个配置桶一个时间序列。 每个预配置的分位数一个时间序列。
分位数误差(详细请参见下面) 由相关桶的宽度将误差限制在观察值维度中。 由一个可配置值将误差限制在φ维度中。
φ-quantile 规范和滑动时间窗口 Prometheus表达式`)。 由客户端预配置。
聚合和滑动时间窗口 Prometheus表达式`)。 通常 不能聚合

注意表格中最后一项的重要性。让我们回到在300毫秒内处理95%请求的SLO。这一次,你不希望显示在300毫秒内处理的请求的百分比,而是显示第95百分位数,即95%请求的请求持续时间。为此,你可以配置一个0.95-quantile的摘要图和5分钟的衰减时间,或者配置一个直方图,在300毫秒标记附近有几个桶,例如,{le="0.1"}, {le="0.2"}, {le="0.3"}, and {le="0.45"}。如果你的服务运行了多个副本实例,那么你将从其中的每一个实例收集请求持续时间,然后你希望将所有内容聚合到整体的第95个百分位数。然而,从摘要图聚合预先计算的分位数很少有意义。在这种特殊情况下,对分位数求平均值会得到统计到无意义的值。


   
       

使用直方图,使用histogram_quantile() 函数`)完全可以实现聚合。


   
       

此外,如果你的SLO发生了变化,你现在想要绘制第90个百分位数,或者您想要考虑最后10分钟而不是最后5分钟,那么您只需调整上面的表达式,而不需要重新配置客户端。

分位数估算误差

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

继续上面的直方图的例子,想象你通常的请求持续时间几乎都非常接近220毫秒,换句话说,如果你能画出“真实的”直方图,你会看到峰值在220毫秒处。在上面配置的Prometheus直方图指标中,几乎所有的观察值,以及第95个百分位数,都将落入标签为{le="0.3"}的桶中,即桶的时间从200毫秒到300毫秒。直方图实现保证了真实的95分位在200毫秒到300毫秒之间。它使用线性插值返回一个单独的值(而不是一个区间),在本例中得到的是295毫秒。计算出的分位数给你的印象是,你即将违反SLO,但实际上,第95百分位数略高于220ms,与SLO的距离在可接受范围之内。

接下来,我们更改后端路由,使所有请求持续时间增加固定的100毫秒。现在,请求持续时间急剧增加到320毫秒,几乎所有的观察结果都会从300毫秒落入450毫秒的桶中。计算出的第95百分位是442.5毫秒,但正确的值接近320ms。虽然你只是偏离了SLO一点点,但计算出的第95分位数看起来更糟。

至少在客户端使用恰当的算法(比如Go客户端使用的算法)的情况下,摘要图都可以计算出正确的百分位数。不幸的是,如果需要聚合来自多个实例的观察结果,则无法使用摘要图。

幸运的是,由于你对桶边界的正确选择,即使在这个人为设计的示例中,观察值的分布非常尖锐,直方图也能够正确地识别你是否在SLO之内或之外。此外,分位数的实际值越接近SLO(换句话说,我们实际上最感兴趣的值),计算值就越精确。

现在让我们再修改一下实验。在新的设置中,请求持续时间的分布峰值为150毫秒,但没有以前那么明显,只占观察值的90%。10%的观测结果在150毫秒到450毫秒之间均匀地分布。在些分布中,第95百分位正好是300毫秒的SLO。使用直方图,计算值是准确的,因为第95百分位的值正好与桶的边界之一相吻合。即使是稍微不同的值仍然是准确的,因为(设计的)相关桶中的均匀分布正是桶中的线性插值所期望的。

摘要图报告的分位数误差现在变得更有趣了。摘要图的分位数误差配置在φ的维度中。在我们的例子中,我们可能配置了0.95±0.01,即计算值将介于第94和第96个百分位之间。上述分布的第94百分位数为270毫秒,第96百分位数为330毫秒。摘要图报告的第95百分位的计算值可以在270毫秒到330毫秒之间的任何位置,不幸的是,这是SLO内部与SLO外部之间的所有差异。

底线是:如果你使用摘要图,你控制φ的维度中的误差。如果使用柱直方图,则可以在观察值的维度上控制误差(通过选择适当的桶布局)。分布广泛,φ变化很小,这样观察值的偏差就会很大。分布很窄,观察值间隔小,将覆盖大间隔φ。

两条经验法则:

  • 如果你需要聚合,请选择直方图。
  • 否则,如果你对将要观察到的值的范围和分布有一个概念,那么就选择直方图。如果需要精确的分位数,请选择摘要图,无论值的范围和分布情况如何。

如果客户端库不支持我需要的指标类型该怎么办?

实现它!欢迎贡献代码。一般来说,我们认为直方图比摘要图需求更迫切。直方图也更容易在客户端库中实现,所以如果有疑问,我们建议先实现直方图。

返回顶部