Prometheus 普罗米修斯作品中的increase()有时会使值加倍:如何避免?
我发现对于一些图,我从普罗米修斯那里得到了双倍值,其中应该只有一个: 我使用的查询:Prometheus 普罗米修斯作品中的increase()有时会使值加倍:如何避免?,prometheus,Prometheus,我发现对于一些图,我从普罗米修斯那里得到了双倍值,其中应该只有一个: 我使用的查询: increase(signups_count[4m]) 刮油间隔设置为2分钟 如果我查询存储的实际数据: curl -gs 'localhost:9090/api/v1/query?query=(signups_count[1h])' "values":[ [1515721365.194, "579"], [1515721485.194, &qu
increase(signups_count[4m])
刮油间隔设置为2分钟
如果我查询存储的实际数据:
curl -gs 'localhost:9090/api/v1/query?query=(signups_count[1h])'
"values":[
[1515721365.194, "579"],
[1515721485.194, "579"],
[1515721605.194, "580"],
[1515721725.194, "580"],
[1515721845.194, "580"],
[1515721965.194, "580"],
[1515722085.194, "580"],
[1515722205.194, "581"],
[1515722325.194, "581"],
[1515722445.194, "581"],
[1515722565.194, "581"]
],
我看到只增加了两次。事实上,如果我查询这些时间,我会看到一个预期的结果:
curl -gs 'localhost:9090/api/v1/query_range?step=4m&query=increase(signups_count[4m])&start=1515721965.194&end=1515722565.194'
"values": [
[1515721965.194, "0"],
[1515722205.194, "1"],
[1515722445.194, "0"]
],
但是Grafana(以及GUI中的Prometheus)倾向于在查询中设置不同的步骤
,对于不熟悉Prometheus内部工作的人来说,我会得到一个非常意外的结果
curl -gs 'localhost:9090/api/v1/query_range?step=15&query=increase(signups_count[4m])&start=1515721965.194&end=1515722565.194'
... skip ...
[1515722190.194, "0"],
[1515722205.194, "1"],
[1515722220.194, "2"],
[1515722235.194, "2"],
... skip ...
我知道,increase()
只是一个例子,我想在这种情况下,它应该是这样工作的
如何避免这种情况?我如何让普罗米修斯/格拉法纳在大多数情况下让我一对一,两对两?除了增加刮擦间隔(这将是我最后的选择)
我理解普罗米修斯,所以如果我不是在任何时候都有一个好的数字,而是在大多数时候有一个好的数字,这对我来说是好的
我还遗漏了什么?这就是信号处理中的一个基本问题。您可以通过提高采样率来改善这一点,4m范围有点短,2m范围有点短。试试10米的距离
例如,这里在151572220执行的查询只看到580@1515722085.194及581@1515722205.194样品。这是在2分钟内增加1,在4分钟内外推是增加2,这是预期的
任何基于度量的监控系统都会有类似的工件,如果您想要100%的准确度,您需要日志。increase()
将始终(大约)是您设置的实际增加量的两倍
原因是(目前实施的):
increase()
是(正如您所观察到的)用于rate()
的语法糖,即rate()
乘以指定范围内的秒数返回的值。在您的情况下,它是rate()*240
rate()
在计算中使用外推。在绝大多数情况下,4分钟的范围将返回正好2个数据点,几乎正好相隔2分钟。然后,速率计算为最后一个和第一个之间的差值(即,您的情况下的2个点)除以2个点的时间差(99.99%的情况下约120秒)乘以您请求的范围(正好240秒)。因此,如果两点之间的增量为零,则速率为零。如果两个点之间的增量为1.0
,则计算的rate()
将接近2.0/240
,因此增量()
将为2.0
(请求的范围-刮取间隔)
并除以请求的范围
,得到(非常接近的)实际增加量,基本上回到普罗米修斯所做的推断
对你来说,这意味着
increase(signups_count[4m]) * (240 - 120) / 240
或者更简洁地说
increase(signups_count[4m]) / 2
它要求你知道射程的长度和刮伤间隔,但它会给你你想要的:“一对一,两对两,大多数时候”。有时你会得到
1.01
,而不是1.0
,因为刮伤间隔119秒,而不是120秒。有时,如果你的评估与刮伤紧密一致,边界上的一些点可能包括在数据点计算中,也可能不包括在数据点计算中,但这仍然是一个比2.0
更好的答案。这不是一个好建议,因为它假定正好有2个样本始终在这个范围内。首先,它对失败的刮伤没有弹性,因为它仍然使用一个过低的范围。其次,它对刮伤的相位和抖动进行了假设,这是你无法依赖的,并且可能会导致答案比它应该的要大得多。它假设在大多数时间内正好有2个样本在这个范围内。这正是OP所要求的:“大多数情况下,一对一,二对二。而纯速率()/increase()在相位和抖动方面有着完全相同的问题:它们产生的答案比它们应该的要大得多(除此之外,他们已经给出了两倍于平均情况下答案大小的事实。此外,您仍然可以使用相同的基本方法进行更长的范围,并且仍然可以改进增加的内容()返回。没有什么强迫您使用2倍的刮取间隔。只是在大多数情况下,您可以并且将得到比增加()更好的答案。请尝试。它提供了increase()
函数,可为缓慢增加的时间序列返回正确的整数结果。此语句“任何基于度量的监控系统都会有类似的工件,如果你想要100%的准确度,你需要日志。”事实上是不正确的,这不仅是普罗米修斯独有的,而且许多人已经向普罗米修斯提交了bug,并提出了解决此问题的建议。