根据 Prometheus 中的速率了解 histogram_quantile

evg*_*y44 9 histogram rate percentile prometheus

根据 Prometheus 文档,为了使用直方图指标获得第 95 个百分点,我可以使用以下查询:

histogram_quantile(0.95, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))
Run Code Online (Sandbox Code Playgroud)

资料来源:https : //prometheus.io/docs/practices/histograms/#quantiles

由于直方图的每个桶都是一个计数器,我们可以计算每个桶的比率为:

范围向量中时间序列的每秒平均增长率。

请参阅:https : //prometheus.io/docs/prometheus/latest/querying/functions/#rate

因此,例如,如果桶值[t-5m] = 100 和桶值[t] = 200,则桶率[t] = (200-100)/(10*60) = 0.167

最后,最令人困惑的部分是 histogram_quantile 函数如何在知道所有桶率的情况下找到给定指标的第 95 个百分位数?

是否有任何代码或算法可以让我更好地理解它?

Ace*_*Ace 42

一个可靠的例子就能很好地解释histogram_quantile

假设:

  • 为简单起见,只有一个系列
  • 10 个公制桶http_request_duration_seconds

10毫秒、50毫秒、100毫秒、200毫秒、300毫秒、500毫秒、1秒、2秒、3秒、5秒

  • http_request_duration_seconds是一个度量类型COUNTER
时间 价值 三角洲 比率(物品数量)
t-10m 50 不适用 不适用
t-5m 100 50 50 / (5*60)
t 200 100 100 / (5*60)
... ... ... ...
  • 我们至少有两次持续 5 分钟的系列刮擦来rate()计算quantity每个桶的

rate_xxx(t) = (value_xxx[t]-value_xxx[t-5m]) / (5m*60)quantity of items为了[t-5m, t]

  • 我们在这里查看 2 个样本(value(t)value(t-5m))。
  • 10000记录了http 请求持续时间 ( items),即
    10000 = rate_10ms(t) + rate_50ms(t) + rate_100ms(t) + ... + rate_5s(t)
桶(le) 10毫秒 50毫秒 100毫秒 200毫秒 300毫秒 500毫秒 1秒 2秒 3秒 5秒 +信息
范围 〜10毫秒 10~50毫秒 50~100毫秒 100~200毫秒 200~300毫秒 300~500毫秒 500毫秒~1秒 1~2秒 2秒~3秒 3~5秒 5秒~
速率_xxx(t) 3000 3000 1500 1000 800 400 200 40 30 5 5

桶是直方图的本质。我们只需要 10 个数字即可rate_xxx(t)进行分位数计算

让我们仔细看看这个表达式(sum()为简单起见,省略了类似的聚合)

histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

我们实际上正在寻找from to95%th中的项目。此处表示我们总共获得了 ( )项。 从上表来看,之前有一起的项目。rate_xxx(t)bucket=10msbucket=+Inf95%th9500th1000010000 * 0.95
9300 = 3000+3000+1500+1000+800bucket=500ms

所以该9500th项目是( ) 中的200th项目( ),其中包含项目9500-9300bucket=500msrange=300~500ms400

普罗米修斯假设桶中的物品以线性模式均匀分布。中项目
的度量值是200thbucket=500ms400ms = 300+(500-300)*(200/400)

即,95%400ms

有几点需要牢记

  • COUNTER指标本质上应该是直方图指标类型
  • 用于分位数计算的系列应始终le定义标签
  • 特定桶中的项目(数据)以线性模式均匀分布(例如:300~500ms)

普罗米修斯至少做出了这个假设

  • 分位数计算需要以某种升序/降序对存储桶进行排序(定义)(例如:1ms < 5ms < 10ms < ...)
  • 的结果histogram_quantile是近似值

PS:
度量值并不总是accurate由于假设Items (Data) in a specific bucket spread evenly a linear pattern

bucket=500ms比如说, ( range=300~500ms)中的实际最大持续时间(例如:来自 nginx 访问日志)是 ,但是,我们将从上面的设置中310ms得到,这有时非常令人困惑。400mshistogram_quantile

斗距越小,精度越高approximation
因此,请设置适合您需要的铲斗距离。


Ela*_*mit 3

我相信是 prometheus 中的代码
一般的想法是,您使用存储桶中的数据来推断/近似分位数 Elasticsearch 在其汇总功能中也做了类似(但不同/更简单)的事情