介绍“@”修饰符

2021年2月18日作者 Ganesh Vernekar

您是否曾选择某个指标的前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将返回http_requests_total2021-01-04T07:40:00+00:00时刻的值。查询rate(http_requests_total[5m] @ 1609746000)将返回http_requests_total在同一时刻的5分钟速率。

此外,start()end() 也可以作为特殊值用于 @ 修饰符。对于范围查询,它们分别解析为范围查询的开始时间和结束时间,并对所有步骤保持不变。对于即时查询,start()end() 都解析为评估时间。

回到 topk() 的修正,以下查询绘制了那些在过去1小时内速率排名前5的 http_requests_total 的1分钟速率。因此,现在您可以理解 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 标志启用。在这篇博客文章中了解更多关于功能标志的信息,并在此处查找 @ 修饰符的文档。