作者:Ganesh Vernekar
你有没有选择过10个时间序列,但得到不是10个,而是100个?如果有,这是给你的。让我带你了解一下潜在的问题是什么,以及我是如何解决它的。
目前,topk()查询仅作为一个即时查询才有意义,你得到确切的k个结果,但当你作为一个范围查询运行它时,你可以得到更多的结果,因为每一步都是独立计算的。这个@修饰符允许你修复范围查询中所有步骤的排名。
在Prometheus v2.25.0中,我们引入了一个新的PromQL修饰符@。与offset修饰符让你对向量选择器、范围向量选择器和子查询的求值进行相对于求值时间的固定时间偏移类似,@修饰符让你对这些选择器的求值进行固定,而不考虑查询求值时间。该语法的功劳归于Björn Rabenstein。
<vector-selector> @ <timestamp>
<range-vector-selector> @ <timestamp>
<subquery> @ <timestamp>
<timestamp>是一个unix时间戳,用float文字描述。
例如,查询http_requests_total @ 1609746000返回的是http_requests_total在2021-01-04T07:40:00+00:00的值。查询rate(http_requests_total[5m] @ 1609746000)返回同时http_requests_total的5分钟速率。
此外,start()和end()也可以作为特殊值作为@修饰符的值。对于范围查询,它们分别解析到范围查询的开始和结束,并且对所有步骤保持相同。对于即时查询,start()和end()都解析为计算时间。
回到topk()修复的讨论,下面的查询绘制了这些系列中http_requests_total的1m速率,它们的最后一个1h速率位于前5位。因此,现在你可以理解topk(),甚至可以将其作为一个范围查询,精确地绘制出k个结果。
rate(http_requests_total[1m]) # This acts like the actual selector.
and
topk(5, rate(http_requests_total[1h] @ end())) # This acts like a ranking function which filters the selector.
类似地,topk()排名可以用其他函数代替,比如histogram_quantile(),它现在只用于即时查询。rate()可以用<aggregation>_over_time()等替换。让我们知道你如何使用这个新的修饰符!
@修饰符默认是禁用的,可以使用标志--enable-feature=promql-at-modifier来启用。在这篇博文[1]中了解更多关于特性标志的信息,并在这里[2]找到@修饰符的文档。
[1]
引入特性标志: https://prometheus.io/blog/2021/02/17/introducing-feature-flags/
[2]
@修饰符文档: https://prometheus.io/docs/prometheus/latest/querying/basics/#modifier