「@」モディファイアの紹介

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は、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()の修正に戻ると、次のクエリは、過去1hのレートが上位5位以内だったシリーズのhttp_requests_total1mレートをプロットします。これにより、k個の結果を正確にプロットするレンジクエリとしてもtopk()を意味のあるものにできるようになりました。

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を使用して有効にできます。機能フラグの詳細については、こちらのブログ記事で確認できます。@モディファイアのドキュメントはこちらにあります。