您是否曾为某些内容选择前 10 个时间序列,但最终得到的不是 10 个而是 100 个?如果是,这篇文章适合您。让我带您了解潜在问题是什么以及我是如何解决的。
目前,topk()
查询仅作为即时查询有意义,在这种情况下您能精确获得 k
个结果,但当您将其作为范围查询运行时,由于每个步骤都是独立评估的,您可能会得到远不止 k
个结果。这个 @
修饰符允许您为范围查询中的所有步骤固定排名。
在 Prometheus v2.25.0 中,我们引入了一个新的 PromQL 修饰符 @
。与 offset
修饰符允许您相对于评估时间将向量选择器、范围向量选择器和子查询的评估偏移一个固定时长类似,@
修饰符允许您固定这些选择器的评估,而无需考虑查询评估时间。此语法的功劳归于 Björn Rabenstein。
<vector-selector> @ <timestamp>
<range-vector-selector> @ <timestamp>
<subquery> @ <timestamp>
<timestamp>
是一个 Unix 时间戳,用浮点数字面量表示。
例如,查询 http_requests_total @ 1609746000
返回 2021-01-04T07:40:00+00:00
时刻 http_requests_total
的值。查询 rate(http_requests_total[5m] @ 1609746000)
返回同一时刻 http_requests_total
的 5 分钟速率。
此外,start()
和 end()
也可以作为 @
修饰符的特殊值使用。对于范围查询,它们分别解析为范围查询的开始时间和结束时间,并且在所有步骤中保持不变。对于即时查询,start()
和 end()
都解析为评估时间。
回到 topk()
的修正,下面的查询绘制了 http_requests_total
中那些在过去 1h
内速率排在前 5 名的时间序列的 1m
速率。因此,现在即使是范围查询,您也可以理解 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
启用。在此博客文章中了解有关功能标志的更多信息,并在此处找到 @
修饰符的文档。