为什么选择直方图?

博客文章在发布后不会更新。这篇文章已经发布一年多了,其内容可能已过时,部分链接可能无效。在依赖任何信息之前,请务必核实。

直方图是一种多值计数器,用于汇总数据点的分布。例如,一个直方图可能有3个计数器,分别统计负值、正值和零值的出现次数。给定一系列数字:3-9760-1,直方图将计数为 2 个负值、1 个零值和 3 个正值。单个直方图数据点最常见的表示方式是条形图。

histogram point as bar chart

上面的例子只有 3 种可能的输出值,但单个直方图中通常会有更多。现实世界中的应用程序通常每分钟导出一个直方图,该直方图汇总前一分钟的指标。通过以这种方式使用直方图,您可以研究数据分布随时间如何变化。

直方图是做什么用的?

直方图有很多用途,但其强大之处在于能够高效地回答关于数据分布的查询。这些查询最常见的是“过去一分钟的平均响应时间是多少?”之类的形式。这些被称为 φ-分位数,通常缩写为 p50 表示第 50 百分位数或 0.5-分位数,也称为中位数。更一般地说,φ-分位数是 N 个观测值中排名为 φ*N 的观测值。

直方图有什么用?

在可观测性领域,直方图的一个常见用例是定义服务级别目标 (SLO)。一个这样的 SLO 示例可能是“>=99% 的所有查询响应时间应小于 30 毫秒”,或者“90% 的所有页面加载在首次绘制后的 100 毫秒内应变得可交互”。

在下图中,您可以看到一些请求在一段时间内的 p50p90p99 响应时间。从数据中可以看出,50% 的请求的响应时间约为 20-30 毫秒或更短,90% 的请求的响应时间约为 80 毫秒或更短,而 99% 的请求的响应时间约为 90 毫秒或更短。您可以非常快速地看到,至少有 50% 的用户获得非常快的响应时间,但几乎所有用户体验到的响应时间都小于 90 毫秒。

p99, p90, and p50 plotted as lines

其他指标类型

如果您已经基于其他指标定义 SLO,该怎么办?您可能考虑过基于 gauges 或 counters 定义 SLO。这种方法可行,但需要您在了解数据分布之前定义 SLO,并且需要在收集时进行复杂的实现。它也很不灵活;如果您决定将 SLO 从“90% 的请求”更改为“99% 的请求”,您需要进行代码更改并发布,然后等待旧数据过期,新指标收集足够的数据才能进行有用的查询。由于直方图从开始到结束都对数据进行建模,因此它们使您能够简单地更改查询并从已收集的数据中获得答案。特别是使用指数直方图,可以以非常低的相对误差率和最小的客户端和分析后端资源消耗来进行任意分布查询。

不使用直方图进行 SLO 定义的不灵活也影响了您衡量 SLO 被违反时影响的能力。例如,假设您正在收集一个计算某些指标的 p99 的 gauge,并基于此定义 SLO。当您的 SLO 被违反并触发警报时,您如何知道它实际上只影响了 1% 的查询、10% 还是 50%?直方图允许您通过查询您感兴趣的分位数来回答这个问题。

另一个选择是将您感兴趣的每个分位数收集为一个 gauge。一些系统,如 Prometheus,原生支持此功能,使用一种有时称为 summary 的指标类型。Summary 可以工作,但它们存在与 gauge 和 counter 相同的灵活性问题,需要您提前决定收集哪些分位数。它们也不能聚合,这意味着无法从两个单独的主机中准确计算出 p90,每个主机都报告自己的 p90

其他数据源和指标类型

您可能会问:“为什么不直接从现有的日志和跟踪数据中计算,而是报告一个单独的指标?”虽然对于某些用例(例如响应时间)来说,这可能是可行的,但对于所有用例而言,这并非总是可行。即使可以从现有数据中计算分位数,您也可能遇到其他问题。您需要确保您的可观测性后端能够在线查询和分析大量现有数据,或者在摄取时对其进行索引和分析。如果您对日志和跟踪进行采样或采用会使数据过时的数据保留策略,您需要确保这些策略不会影响派生指标,或者已正确加权,否则您可能会无法准确评估您的 SLO。根据您的采样策略,甚至可能无法实现。使用直方图是避免这些细微问题的有效方法(如果这些问题适用于您)。

本文的一个版本 最初发布 在作者的博客上。