介绍 '@' 修饰符

您是否曾为某些内容选择前 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 启用。在此博客文章中了解有关功能标志的更多信息,并在此处找到 @ 修饰符的文档。