Introducing the '@' Modifier

February 18, 2021作者 Ganesh Vernekar

您是否曾尝试选择某个指标的前 10 个时间序列,结果却得到了 100 个而不是 10 个? 如果是,那么本文就是为您准备的。我将向您介绍底层问题以及我如何解决它。

目前,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 启用。 在 这篇博文 中了解有关功能标志的更多信息,并在 此处 找到 @ 修饰符的文档。