我是否正确理解了普罗米修斯的速率和增长函数?

我已经仔细阅读了 普罗米修斯文件,但它对我来说还是有点不清楚,所以我来这里确认我的理解。

(请注意,为了尽可能简单的例子,我使用了一秒刮取间隔,计时范围-即使在实践中是不可能的) < br > < br > 尽管我们每秒刮下一个计数器,计数器的数值现在是30。我们有以下的时间序列: < br >

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

我们想对这个数据集运行一些查询。

1. 利率()
官方文件说:
速率(v 距离向量) : 计算距离向量中时间序列的每秒平均增长率

对于外行人来说,这意味着我们将得到每秒的增量,而给定秒的值将是给定范围内的平均增量?

我的意思是:
Rate (counter [1s ]) : 将匹配 ICH,因为平均值将仅从一个值计算。
速率(计数器[2秒]) : 将在2秒内从增量中获得平均值,并将其分配到秒中
所以在前2秒,我们得到了总增量3,这意味着平均值是1.5/秒。 最终结果:

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

速率(计数器[5s ]) : 将在5秒内从增量中获得平均值,并将其分配到秒中
与[2秒]相同,但是我们从总增量5秒计算平均值。 最终结果:

second result
1        2
2        2
3        2
4        2
5        2
6        4
7        4
8        4
9        4
10       4

因此,时间范围越高,我们将得到更平滑的结果。这些增加的总和将与实际的计数器相匹配。

2. 增加()
官方文件说:
“增加(v 范围向量) : 计算范围向量中时间序列的增加。”< br > < br > 对我来说,这意味着它不会将平均值分布在秒之间,而是显示给定范围的单次增量(通过外推)。
暴增(计数器[1秒]) : 在我的术语中,这将与 ICH 和1秒的速率相匹配,只是因为总范围和速率的基本粒度相匹配。
增加(计数器[2秒]) : 前2秒我们总共增加了3点,所以 秒将得到3的值,以此类推..。

  second result
1        3*
2        3
3        4*
4        4
5        7*
6        7
7        7*
8        7
9        9*
10       9

用我的话来说,这些数值意味着每一秒的外推数值。

我是理解得很好,还是远远不够?

62083 次浏览

在理想情况下(样本的时间戳恰好在第二个时间戳上,规则计算恰好在第二个时间戳上) ,rate(counter[1s])将返回恰好的 ICH 值,而 rate(counter[5s])将返回 ICH 值和前4个时间戳的平均值。除了第二个1的 ICH 是0,而不是1,因为没有人知道你的计数器什么时候是0: 也许它在那里增加了,也许它昨天增加了,从那以后一直保持在1。(这就是为什么第一次出现值为1的计数器时不会出现增量的原因——因为您的代码刚刚创建并增量了它。)

increase(counter[5s])正好是 rate(counter[5s]) * 5(increase(counter[2s])正好是 rate(counter[2s]) * 2)。

现在,在现实世界中发生的情况是,您的样本并不是在第二个时刻准确地每秒收集一次,而且规则评估也不会在第二个时刻准确地发生。因此,如果你有一大堆的样本,是(或多或少)1秒钟的间隔,你使用普罗米修斯的 rate(counter[1s]),你将得不到输出。这是因为普罗米修斯所做的就是取出1秒范围内的所有样本 [now() - 1s, now()](在绝大多数情况下都是单个样本) ,尝试计算一个速率,但失败了。

如果你查询 rate(counter[5s]) OTOH,普罗米修斯会选取 [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秒。

由于样本间距不够精确,rateincrease通常都会返回整数计数器的浮点值(这对于 rate来说很明显,但对于 increase来说就不那么明显了)。

* * 解释分析相反方向的问题 * *

假设我们有

rate(some_metric_name_count [3m]) = 2

这意味着在时间点计数器之前的3分钟时间间隔内,计数器每秒增加2个,3分钟之后,这个计数器增加了2 * 180(秒) = 360。

这也意味着在这种情况下:

increase(some_metric_name_count [3m]) ~ 360

在引擎盖下面主要有第一个时间点的轻微近似,所以可以有2个意思的绝对误差:

increase(some_metric_name_count [3m]) = 360 +/- 2

包括从[358,362]开始的音程,包括音程的末尾

普罗米修斯计算时间戳 trate(counter[d])的方法如下:

  1. 它在 (t-d ... t]时间范围内为 counter时间序列选择原始样品。请注意,t-d时间戳不包括在时间范围内,而 t时间戳包括在时间范围内。如果选定的时间范围包含少于两个原始样本,则普罗米修斯返回时间戳 t处的空值(间隙)。
  2. 然后计算所选原始样品的增量。通常它被计算为最后选择的样品和第一个选择的样品之间的差异。如果在选定的时间范围内将 counter重置为零,则计算会变得稍微复杂一些。为了清楚起见,我们跳过这一步。
  3. 然后,如果第一个和/或最后一个原始样本的时间戳距离选定时间范围的界限太远,则可以外推得到的增加。
  4. 然后通过外推增加除以 d来计算速率。

除了最后一步,普罗米修斯用同样的方法计算 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
  • rate(counter[1s])在任何时间戳 t都不会返回任何东西,因为任何时间范围 (t-1s ... t]只包含一个原始样本,而普罗米修斯需要至少两个样本来计算 rate()increase()

  • 当不进行外推时,rate(counter[2s])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

实际上,由于外推的原因,rate(counter[2s])increase(counter[2s])的普罗米修斯结果可能稍大一些,因为所选时间范围内的第一个样本位于相对远离时间范围开始的地方。

这种计算有以下问题:

  • 普罗米修斯可以返回 increase()随时间序列的分数结果,其中只包含整数值。这是因为外推。例如,普罗米修斯可能返回来自 increase(http_requests_total[5m])的分数结果。

  • 普罗米修斯从 increase(counter[d])rate(counter[d])返回空结果(也就是空白) ,如果后视窗 d没有覆盖至少两个样本——参见上面的 rate(counter[1s])increase(counter[1s])示例。

  • 普罗米修斯完全错过了 (t-d ... t]间隔前的原始样品和这个间隔的第一个原始样品之间的增加。这可能导致计算不准确。例如,increase(counter[1h])不等于 sum_over_time(increase(counter[1m])[1h:1m])

普罗米修斯开发人员意识到了这些问题——参见 这个链接。这些问题在我工作的系统中解决-维多利亚公式-更具体地说,在 MetricsQL查询语言中-参见 此评论这篇文章获取技术细节。