一文搞懂 Prometheus 的直方图

news/2024/5/19 0:31:02 标签: prometheus, histogram, quantile

原文链接:一文搞懂 Prometheus 的直方图

Prometheus 中提供了四种指标类型(参考:Prometheus 的指标类型),其中直方图(Histogram)和摘要(Summary)是最复杂和难以理解的,这篇文章就是为了帮助大家加深对这 histogram 类型指标的理解。

1. 什么是 Histogram?

根据上篇文档,Histogram 会在一段时间范围内对数据进行采样(通常是请求持续时间或响应大小等),并将其计入可配置的存储桶(bucket)中。但这句话还是不太好理解,下面通过具体的示例来说明。

假设我们想监控某个应用在一段时间内的响应时间,最后监控到的样本的响应时间范围为 0s~10s。现在我们将样本的值域划分为不同的区间,即不同的 bucket,每个 bucket 的宽度是 0.2s。那么第一个 bucket 表示响应时间小于等于 0.2s 的请求数量,第二个 bucket 表示响应时间大于 0.2s 小于等于 0.4s 的请求数量,以此类推。

Prometheus 的 histogram 是一种累积直方图,与上面的区间划分方式是有差别的,它的划分方式如下:还假设每个 bucket 的宽度是 0.2s,那么第一个 bucket 表示响应时间小于等于 0.2s 的请求数量,第二个 bucket 表示响应时间小于等于 0.4s 的请求数量,以此类推。也就是说,每一个 bucket 的样本包含了之前所有 bucket 的样本,所以叫累积直方图。

2. 为什么是累积直方图?

上节内容告诉我们,Prometheus 中的 histogram 是累积的,这是很奇怪的,因为通常情况下非累积的直方图更容易理解。Prometheus 为什么要这么做呢?

想象一下,如果 histogram 类型的指标中加入了额外的标签,或者划分了更多的 bucket,那么样本数据的分析就会变得越来越复杂。如果 histogram 是累积的,在抓取指标时就可以根据需要丢弃某些 bucket,这样可以在降低 Prometheus 维护成本的同时,还可以粗略计算样本值的分位数。通过这种方法,用户不需要修改应用代码,便可以动态减少抓取到的样本数量。

假设某个 histogram 类型指标的样本数据如下:

现在我们希望 Prometheus 在抓取指标时丢弃响应时间在 100ms 以下的 bucket,就可以通过下面的 relabel 配置来实现:

其中,example_latency_seconds_bucket 用来匹配标签 __name__ 的值,'0.0.*' 用来匹配标签 `le` 的值,即 `le` 的值为 `0.0x`。然后将匹配到的样本丢弃。

通过这种方法,你可以丢弃任意的 bucket,但不能丢弃 le="+Inf" 的 bucket,因为 histogram_quantile 函数需要使用这个标签。

另外 histogram 还提供了 _sum 指标和 _count 指标,即使你丢弃了所有的 bucket,仍然可以通过这两个指标值来计算请求的平均响应时间。

通过累积直方图的方式,还可以很轻松地计算某个 bucket 的样本数占所有样本数的比例。例如,想知道响应时间小于等于 1s 的请求占所有请求的比例,可以通过以下公式来计算:

example_latency_seconds_bucket{le="1.0"} / ignoring (le) example_latency_seconds_bucket{le="+Inf"}

3. 分位数计算

Prometheus 通过 histogram_quantile 函数来计算分位数(quantile),而且是一个预估值,并不完全准确,因为这个函数是假定每个区间内的样本分布是线性分布来计算结果值的。预估的准确度取决于 bucket 区间划分的粒度,粒度越大,准确度越低。以下图为例:

假设有 10000 个样本,第 9501 个样本落入了第 8 个 bucket。第 8 个 bucket 总共有 368 个样本,其中第 9501 个样本在该 bucket 中属于第 93 个样本。

根据 Prometheus 源代码文件 promql/quantile.go 第 108 行的公式:

return bucketStart + (bucketEnd-bucketStart)*float64(rank/count)

我们可以计算(quantile=0.95)的样本值为:

这个值已经很接近精确的分位数值了。关于 histogram_quantile 函数的详细使用方式,请参考:[PromQL 内置函数](https://www.yangcs.net/prometheus/3-prometheus/functions.html#histogramquantile)。

4. 总结

本文主要介绍了 histogram 的工作原理以及分位数的计算方法,相信通过本文的抛砖引玉,大家应该对 Prometheus 的 histogram 有了更深一步的了解,下篇文章将会为大家呈现 Summary 的工作方式。

5. 参考资料

  • Prometheus and Histograms
    ----


http://www.niftyadmin.cn/n/1751187.html

相关文章

leetcode学java,Java开发必备的10大学习网站

原标题:Java开发必备的10大学习网站Java开发必备的10大学习网站Java网站开发必知1.StackoverflowStackoverflow.com可能是编程界中最流行的网站了,是一个与程序相关的IT技术问答网站,用户可以在网站免费提交问题,浏览问题,索引相关…

在.NET Core控制台应用程序中使用强类型配置

想象一下,你写一个控制台应用程序,你想要从配置文件中以强类型方式读取配置。 .NET Core 可以帮助我们解决。 通常我会在ASP.NET Core MVC中演示,但简单起见,只在控制台应用程序中演示。 让我们创建两个配置类,用于保…

编译android系统提示不支持64位系统的解决方法

在使用:$ repo init -u git://Android.git.kernel.org/platform/manifest.git$ repo sync下载完代码后,进行make,$cd ~/mydroid$make却出现了如下错误:build/core/main.mk:73: You are attempting to build on a 32-bit system.bu…

dogepool.pw index.php,php – 在Dogecoin转换欧元

所以我打算将dogecoin整合到我的busniess网站上.我的产品可以用欧元货币购买,并且可以在doecoin中提供,我需要将EURO兑换成Dogecoin.我有什么DID:我在php中找到了DOGECOIN API(https://www.dogeapi.com).我发现我们可以转换BTC或USD中的DOGECOIN.使用这个&#xff1…

Kubernetes Pod 驱逐详解

原文链接:Kubernetes Pod 驱逐详解 在 Kubernetes 中,Pod 使用的资源最重要的是 CPU、内存和磁盘 IO,这些资源可以被分为可压缩资源(CPU)和不可压缩资源(内存,磁盘 IO)。可压缩资源不…

JS双击div编辑文本内容

HTML代码&#xff1a; <div class"album"><div class"image"><a href"javascript:;" οnclick"view({$vo.id})"><img src"{$vo.img}" /></a></div><div class"name" id&q…

Bitmap的加载和Cache

由于Bitmap的特殊性以及Android对单个应用所施加的内存限制&#xff0c;比如16M&#xff0c;这导致加载Bitmap的时候很容易出现内存溢出。比如以下场景&#xff1a; java.lang.OutofMemoryError:bitmap size exceeds VM budget Android中常用的缓存策略也是很有意思&#xff0c…

Gearman 性能调优

Gearman是最早由LiveJournal内部开发并使用的一个通用并行任务调度框架&#xff0c;允许不同语言直接通过非常简单的方式进行互操作。前台提交工作任务(Task)和参数&#xff0c;由后台工作进程(Worker)完成实际工作。 例如前台提交用户需要进行渲染的图片&#xff0c;由Gearman…