我已经仔细阅读了Prometheus文档,但是对我来说仍然不清楚,所以我在这里是对我的理解的确认。
(请注意,为了尽可能简单的示例,我在废品间隔时间范围中使用了1秒-即使实际上不可能这样做)
尽管我们每秒都废品一个计数器并且该计数器的值为30。为此,我们有以下时间序列:
second counter_value increase calculated by hand(call it ICH from now)
1 1 1
2 3 2
3 6 3
4 7 1
5 10 3
6 14 4
7 17 3
8 21 4
9 25 4
10 30 5
Run Code Online (Sandbox Code Playgroud)
我们要对该数据集运行一些查询。
1.rate()
官方文档指出:
“ rate(v范围向量):计算范围向量中时间序列的每秒平均增长率。”
用外行术语来说,这意味着我们将获得每秒的增量,而给定秒的值将是给定范围内的平均增量?
这是我的意思:
rate(counter [1s]):将与ICH匹配,因为平均值将仅根据一个值计算。
rate(counter [2s]):将从2秒的增量中获取平均值,并将其分配到秒数中。
因此,在前2秒中,我们获得了总计3的增量,这意味着平均值为1.5 / sec。最后结果:
second result
1 1,5
2 1,5
3 2
4 2
5 3,5
6 3,5
7 3,5
8 3,5
9 4,5
10 4,5
Run Code Online (Sandbox Code Playgroud)
rate(counter [5s]):将从5秒的增量中获取平均值,并将其分配到秒中
。与[2s]相同,但我们从5sec的总增量中计算平均值。最后结果:
second result
1 2
2 2
3 2
4 2
5 2
6 4
7 4
8 4
9 4
10 4
Run Code Online (Sandbox Code Playgroud)
因此,时间范围越高,我们得到的结果越平滑。这些增加的总和将与实际计数器匹配。
2.increase()
官方文档指出:
“ increase(v range-vector):计算范围向量中时间序列的增加。”
对我来说,这意味着它不会在几秒钟内分配平均值,而是显示给定范围内的单个增量(外推)。
增加(counter [1s]):在我的术语中,这将与ICH和1s的速率匹配,只是因为总范围和速率的基本粒度匹配。
增加(counter [2s]):前2秒使我们总共增加了3,所以2秒将得到3的值,依此类推...
second result
1 3*
2 3
3 4*
4 4
5 7*
6 7
7 7*
8 7
9 9*
10 9
Run Code Online (Sandbox Code Playgroud)
*以我的观点,这些值表示每秒覆盖的外推值。
我理解得好还是离那很远?
val*_*ala 33
Prometheus按以下方式计算rate(counter[d])时间戳:t
counter它在时间范围内选择时间序列的原始样本(t-d ... t]。注意,t-d时间戳不包含在时间范围内,而t时间戳包含在时间范围内。如果所选时间范围包含少于两个原始样本,则 Prometheus 在时间戳处返回一个空值(间隙)t。counter在选定的时间范围内将 重置为零,计算会变得稍微复杂。为了清楚起见,让我们跳过这个。d。除了最后一步外, Prometheus 的计算increase(counter[d])方式相同。
让我们看几个应用于原始数据的示例:
second counter_value increase calculated by hand(call it ICH from now)
1 1 1
2 3 2
3 6 3
4 7 1
5 10 3
6 14 4
7 17 3
8 21 4
9 25 4
10 30 5
Run Code Online (Sandbox Code Playgroud)
rate(counter[1s])在任何时间戳 都不会返回任何内容,t因为任何时间范围(t-1s ... t]仅包含单个原始样本,而 Prometheus 需要至少两个样本来计算rate()和increase()。
当未应用外推法时,rate(counter[2s])and将increase(counter[2])针对每个时间戳返回以下值:t
t counter_value rate(counter[2s]) increase(counter[2s])
1 1 - -
2 3 (3-1)/2=1.0 3-1=2
3 6 (6-3)/2=1.5 6-3=3
4 7 (7-6)/2=0.5 7-6=1
5 10 (10-7)/2=1.5 10-7=3
6 14 (14-10)/2=2 14-10=4
7 17 (17-14)/2=1.5 17-14=3
8 21 (21-17)/2=2 21-17=4
9 25 (25-21)/2=2 25-21=4
10 30 (30-25)/2=2.5 30-25=5
Run Code Online (Sandbox Code Playgroud)
实际上,Prometheus 的结果rate(counter[2s])和increase(counter[2s])可能会因外推而稍大一些,因为所选时间范围内的第一个样本距离时间范围的起点相对较远。
这样的计算存在以下问题:
Prometheus 可以返回increase()时间序列中的分数结果,其中仅包含整数值。这是因为外推法。例如,Prometheus 可能会返回来自 的分数结果increase(http_requests_total[5m])。
当回溯窗口未覆盖至少两个样本时,Prometheus 返回空结果(也称为间隙)increase(counter[d])-请参阅上面的和示例。rate(counter[d])drate(counter[1s])increase(counter[1s])
(t-d ... t]Prometheus 完全错过了该间隔之前的原始样本与该间隔内的第一个原始样本之间的增量。这可能会导致计算不准确。例如,increase(counter[1h])不等于sum_over_time(increase(counter[1m])[1h:1m])。
Prometheus 开发人员已经意识到这些问题 - 请参阅此链接。这些问题在我工作的系统 - VictoriaMetrics - 更具体地说,在MetricsQL查询语言中得到解决 - 有关技术细节,请参阅此评论和本文。
小智 17
**反方向分析问题的解释**
假设我们有
rate(some_metric_name_count [3m]) = 2
Run Code Online (Sandbox Code Playgroud)
这意味着在该时间点之前的 3 分钟间隔内,计数器每秒增加 2,而在 3 分钟之后,该计数器增加了 2*180(秒)= 360。
这也意味着在这种情况下:
increase(some_metric_name_count [3m]) ~ 360
Run Code Online (Sandbox Code Playgroud)
主要针对第一个时间点,在幕后有一些轻微的近似值,因此可能存在 2 的绝对误差,这意味着:
increase(some_metric_name_count [3m]) = 360 +/- 2
Run Code Online (Sandbox Code Playgroud)
涵盖 [358, 362] 的区间,包括区间的结尾
Ali*_*ean 12
在理想的世界中(样本的时间戳恰好在第二个时间戳上,规则评估恰好在第二个时间戳上发生)rate(counter[1s])将完全返回您的ICH值,并且rate(counter[5s])将返回该ICH和前4个的平均值。是0,而不是1,因为没人知道您的计数器何时为零:也许它在那增加,也许昨天就增加了,从那以后一直保持在1。(这就是为什么您第一次看到计数器值为1时看不到增加的原因-因为您的代码刚刚创建并递增了。)
increase(counter[5s])完全是rate(counter[5s]) * 5(并且increase(counter[2s])完全是rate(counter[2s]) * 2)。
现在,在现实世界中发生的事情是,您的样本并非每秒都精确地每秒收集一次,规则评估也并非每秒都准确地进行一次。因此,如果您有一堆(或多或少)相距1秒的样本并且使用Prometheus' rate(counter[1s]),则不会获得任何输出。这是因为Prometheus所做的是将所有样本都置于1秒范围内[now() - 1s, now()](在大多数情况下,这将是单个样本),试图计算出速率并失败。
如果您查询rate(counter[5s])OTOH,则Prometheus将选择该范围内的所有样本[now() - 5s, now](例如5个样本,平均覆盖大约4秒[t1, v1], [t2, v2], [t3, v3], [t4, v4], [t5, v5]),并且(假设您的计数器在该间隔内未重置)将返回(v5 - v1) / (t5 - t1)。即,它实际上计算的是〜4s而不是5s的增加速率。
increase(counter[5s])将返回(v5 - v1) / (t5 - t1) * 5,因此增加速率超过〜4秒,外推至5秒。
由于样本之间的间距不正确,两者rate和increase经常会返回整数计数器的浮点值(这对显然很有意义rate,但对而言意义不大increase)。