サブクエリのサポート

2019年1月28日筆者: Ganesh Vernekar

はじめに

タイトルの通り、サブクエリはクエリの一部であり、従来は不可能だったクエリ内での範囲クエリを可能にします。これは長らく要望されていた機能です。prometheus/prometheus/1227

サブクエリサポートのプルリクエストが最近Prometheusにマージされ、Prometheus 2.7で利用可能になります。以下で詳しく見ていきましょう。

動機

時として、低い解像度/範囲(例: 5m)でrateを使用して問題を特定したいが、そのデータをより高い範囲(例: 1hmax_over_time)で集計したい場合があります。

以前は、上記のようなことを単一のPromQLクエリで行うことは不可能でした。アラートルールやグラフ作成のためにクエリで範囲選択を行いたい場合、そのクエリに基づいたレコーディングルールを作成し、レコーディングルールによって作成されたメトリクスで範囲選択を行う必要がありました。例: max_over_time(rate(my_counter_total[5m])[1h])

数日または数週間にわたるデータに対して迅速な結果を得たい場合、レコーディングルールに十分なデータが蓄積されるまで待つ必要があり、時間がかかることがあります。レコーディングルールを追加し忘れると、フラストレーションが溜まることもあります。また、クエリの各ステップに対してレコーディングルールを作成するのは面倒です。

サブクエリのサポートにより、これらすべての待機とフラストレーションは解消されます。

サブクエリ

サブクエリは、/api/v1/query_range API呼び出しに似ていますが、インスタントクエリ内に埋め込まれています。サブクエリの結果は範囲ベクトルです。

Prometheusチームは、ミュンヘンで開催されたPrometheus Dev Summit 2018でサブクエリの構文について合意に達しました。これらはサブクエリサポートに関するサミットの議事録であり、サブクエリサポートの実装に使用された構文の設計ドキュメントの概要です。

<instant_query> '[' <range> ':' [ <resolution> ] ']' [ offset <duration> ]
  • <instant_query>は、/query_range APIのqueryフィールドに相当します。
  • <range>offset <duration>は、範囲セレクタに似ています。
  • <resolution>はオプションであり、/query_range APIのstepに相当します。

解像度が指定されていない場合、グローバルな評価間隔がサブクエリのデフォルト解像度として使用されます。また、サブクエリのステップは独立してアラインメントされ、親クエリの評価時間には依存しません。

min_over_time関数内のサブクエリは、過去30分間のhttp_requests_totalメトリクスの5分間レートを、1分間の解像度で返します。これは、query=rate(http_requests_total[5m]), end=<now>, start=<now>-30m, step=1mという/query_range API呼び出しに相当し、受信したすべての値の最小値を取るものです。

min_over_time( rate(http_requests_total[5m])[30m:1m] )

内訳

  • rate(http_requests_total[5m])[30m:1m]がサブクエリであり、rate(http_requests_total[5m])が実行されるクエリです。
  • rate(http_requests_total[5m])は、start=<now>-30mからend=<now>まで、1mの解像度で実行されます。start時間は1mのステップで独立してアラインメントされることに注意してください(アラインメントされたステップは0m 1m 2m 3m ...です)。
  • 最終的に、上記のすべての評価結果がmin_over_time()に渡されます。

以下は、ネストされたサブクエリとデフォルト解像度の使用例です。最も内側のサブクエリは、一定期間のdistance_covered_meters_totalのレートを取得します。これを使用して、再び一定期間のレートのderiv()を取得します。そして最終的に、すべての導関数の最大値を取ります。最も内側のサブクエリの<now>時間は、deriv()での外側のサブクエリの評価時間からの相対値であることに注意してください。

max_over_time( deriv( rate(distance_covered_meters_total[1m])[5m:1m] )[10m:] )

ほとんどの場合、デフォルトの評価間隔が必要になります。これは、ルールがデフォルトで評価される間隔です。カスタム解像度は、計算頻度を低く/高くしたい場合、例えば計算コストの高いクエリをより頻繁に計算したくない場合などに役立ちます。

エピローグ

サブクエリはレコーディングルールの代わりとして非常に便利ですが、不必要に使用するとパフォーマンスに影響します。パフォーマンス向上のために、重いサブクエリは最終的にレコーディングルールに変換する必要があります。

また、レコーディングルール内にサブクエリを含めることは推奨されません。レコーディングルールでサブクエリを使用する必要がある場合は、代わりに複数のレコーディングルールを作成してください。