“@”修饰符介绍

2021年2月18日作者 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 会返回 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的时间序列的 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 标志来启用。请通过这篇博客文章了解更多关于特性标志的信息,并在此处查找 @ 修饰符的文档。