“@”修饰符介绍
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_total
在 2021-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
标志来启用。请通过这篇博客文章了解更多关于特性标志的信息,并在此处查找 @
修饰符的文档。