用 Prometheus 作业务监控,需要统计“今日请求量”,很自然想到用 increase 函数。实际效果是它不返回整数,甚至在突然的压力下“请求量”还会减少。为什么会发生这些现象呢?

原因是 increase/rate 函数对区间的统计信息做了“线性外插”,是一个估算值。

Prometheus 怎么做线性外插

如下图:我们每隔 5s 采样一次,问在 [3s, 23s] 的区间内增长了多少?这里的问题在于查询区间的时间与采样时间不重合,因此并没法得到准确的数值。

Prometheus 的策略是拿到样本的端点 {5s: 10}{20s: 30},并计算它们的区间为20 - 5 = 15s,期间请求量增长了 30 - 10 = 10 次。因此推算每秒增长了 20/15次,按增长率估算在[3s, 23] 这 20s 期间,增长了 20 * (20/15) = 26.67 次。

线性插值是假设数据线性增长进行推测,而“外插”则表示推测的数据范围数据 [3s, 23s] 在样本点定义域 [5s, 20s]

当然 Prometheus 还考虑了其它一些极端情况,如样本点太少,数据归零等情形,这里不作说明。

为什么请求量会减少?

在突然的高压力下,数据就不再是“线性”分布,此时线性外插就会失真。如下图:

考虑 [5s, 10s] 区间时,增长率为每秒 8 次,而在考虑 [5s, 15s] 时只有每秒 4.2 次,只有之前的近一半。从而导致外插后的请求量反而减少了。

参考