原文链接:一文搞懂 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 内置函数

4. 总结

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

5. 参考资料


一文搞懂 Prometheus 的直方图的更多相关文章

  1. 一文搞懂RAM、ROM、SDRAM、DRAM、DDR、flash等存储介质

    一文搞懂RAM.ROM.SDRAM.DRAM.DDR.flash等存储介质 存储介质基本分类:ROM和RAM RAM:随机访问存储器(Random Access Memory),易失性.是与CPU直接 ...

  2. 基础篇|一文搞懂RNN(循环神经网络)

    基础篇|一文搞懂RNN(循环神经网络) https://mp.weixin.qq.com/s/va1gmavl2ZESgnM7biORQg 神经网络基础 神经网络可以当做是能够拟合任意函数的黑盒子,只 ...

  3. Web端即时通讯基础知识补课:一文搞懂跨域的所有问题!

    本文原作者: Wizey,作者博客:http://wenshixin.gitee.io,即时通讯网收录时有改动,感谢原作者的无私分享. 1.引言 典型的Web端即时通讯技术应用场景,主要有以下两种形式 ...

  4. 一文搞懂vim复制粘贴

    转载自本人独立博客https://liushiming.cn/2020/01/18/copy-and-paste-in-vim/ 概述 复制粘贴是文本编辑最常用的功能,但是在vim中复制粘贴还是有点麻 ...

  5. 三文搞懂学会Docker容器技术(中)

    接着上面一篇:三文搞懂学会Docker容器技术(上) 6,Docker容器 6.1 创建并启动容器 docker run [OPTIONS] IMAGE [COMMAND] [ARG...] --na ...

  6. 三文搞懂学会Docker容器技术(下)

    接着上面一篇:三文搞懂学会Docker容器技术(上) 三文搞懂学会Docker容器技术(中) 7,Docker容器目录挂载 7.1 简介 容器目录挂载: 我们可以在创建容器的时候,将宿主机的目录与容器 ...

  7. 一文搞懂所有Java集合面试题

    Java集合 刚刚经历过秋招,看了大量的面经,顺便将常见的Java集合常考知识点总结了一下,并根据被问到的频率大致做了一个标注.一颗星表示知识点需要了解,被问到的频率不高,面试时起码能说个差不多.两颗 ...

  8. 一文搞懂 js 中的各种 for 循环的不同之处

    一文搞懂 js 中的各种 for 循环的不同之处 See the Pen for...in vs for...of by xgqfrms (@xgqfrms) on CodePen. for &quo ...

  9. 一文搞懂如何使用Node.js进行TCP网络通信

    摘要: 网络是通信互联的基础,Node.js提供了net.http.dgram等模块,分别用来实现TCP.HTTP.UDP的通信,本文主要对使用Node.js的TCP通信部份进行实践记录. 本文分享自 ...

随机推荐

  1. nginx实战操作(常用命令及配置)

    1. nginx介绍 2. nginx常用命令 验证配置是否正确: nginx -t 查看Nginx的详细的版本号:nginx -V 查看Nginx的简洁版本号:nginx -v 启动Nginx:st ...

  2. [Haoi2016]字符合并 题解

    tijie 时间限制: 2 Sec  内存限制: 256 MB 题目描述 有一个长度为 n 的 01 串,你可以每次将相邻的 k 个字符合并,得到一个新的字符并获得一定分数.得到的新字 符和分数由这 ...

  3. springcloud-注册中心快速构建

    1. 场景描述 springcloud提供了一整套可行的构建分布式系统的方案,使的企业/开发人员能够快速沟通分布式系统,今天快速构建下springcloud的注册中心Eureka. 2. 解决方案 2 ...

  4. 【基础算法模拟+例题】-C++

    在漫长的刷题练习过程中,几乎所有稍微熟练一点的OIer都会,但是都几乎没有经过系统的学习,今天,我们就来讲讲模拟算法,也是为了复习emm. 定义? 定义?模拟还有什么定义吗? 那什么是模拟呢? 就是按 ...

  5. rabbitmq升级新版本后,需要新建用户。新版本默认禁止别的机器用guest用户访问。

    rabbitmq升级新版本后,需要新建用户.新版本默认禁止别的机器用guest用户访问.

  6. sublime 如何安装插件实现高效输入,如何支持markdown 语法,并实时预览

    啊,一直想鼓捣markdown的语法,但是配置什么的有点麻烦.不过用起来的话,真心顺手.无需考虑格式与语法点来点去影响效率, 用心去搬砖,用脚修bug 一.初识 Package Control 首先, ...

  7. DML语言DDL

    DML(data manipulation language): 它们是SELECT.UPDATE.INSERT.DELETE,就象它的名字一样,这4条命令是用来对数据库里的数据进行操作的语言 . D ...

  8. SP1026 FAVDICE - Favorite Dice[期望DP]

    也许更好的阅读体验 \(\mathcal{Description}\) 一个\(n\)面的骰子,求期望掷几次能使得每一面都被掷到 输入有\(T\)组数据,每次输入一个\(n\) 输出保留两位小数 \( ...

  9. c语言进阶15-数据结构总结

    数据结构结论 1.阿基米德说过:“给我一个支点,我就能翘起地球”. 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成.记为:Data_Structure=(D, ...

  10. [LeetCode] 107 Binary Tree Level Order Traversal II (easy)

    原题 层序遍历,从自底向上按层输出. 左→右→中 解法一 : DFS,求出自顶向下的,最后返回时反转一下. class Solution { public: vector<vector<i ...