web-dev-qa-db-ja.com

Prometheusの増加()は値を2倍にすることがあります:回避するには?

一部のグラフでは、Prometheusからdoubles値を取得しますが、1つだけでなければなりません。

Graph with twos above bars

私が使用するクエリ:

_increase(signups_count[4m])
_

スクレイピング間隔は、2分の 推奨最大値 に設定されています。

保存されている実際のデータをクエリすると:

_curl -gs 'localhost:9090/api/v1/query?query=(signups_count[1h])'

"values":[
     [1515721365.194, "579"],
     [1515721485.194, "579"],
     [1515721605.194, "580"],
     [1515721725.194, "580"],
     [1515721845.194, "580"],
     [1515721965.194, "580"],
     [1515722085.194, "580"],
     [1515722205.194, "581"],
     [1515722325.194, "581"],
     [1515722445.194, "581"],
     [1515722565.194, "581"]
],
_

増加が2つしかないことがわかります。実際、これらの時間についてクエリを実行すると、予期した結果が表示されます。

_curl -gs 'localhost:9090/api/v1/query_range?step=4m&query=increase(signups_count[4m])&start=1515721965.194&end=1515722565.194'

"values": [
     [1515721965.194, "0"],
     [1515722205.194, "1"],
     [1515722445.194, "0"]
],
_

しかし、Grafana(およびGUIのPrometheus)は、異なるstepをクエリに設定する傾向があり、これにより、Prometheusの内部動作に慣れていない人には非常に予期しない結果が得られます。

_curl -gs 'localhost:9090/api/v1/query_range?step=15&query=increase(signups_count[4m])&start=1515721965.194&end=1515722565.194'

... skip ...
 [1515722190.194, "0"],
 [1515722205.194, "1"],
 [1515722220.194, "2"],
 [1515722235.194, "2"],
... skip ...
_

increase()が単なる rate() functionの特定のユースケースの構文糖 であることを知っているので、これは、状況。

そのような状況を回避する方法は?ほとんどの場合、Prometheus/Grafanaで1対1、2対2を表示するにはどうすればよいですか?かき取り間隔を長くする以外は(これが私の最後の手段になります)。

Prometheus exactの種類のツールではない であることを理解しているので、良いものがあれば私には問題ありません常にではありませんが、ほとんどの場合。

ここで他に何が欠けていますか?

14
sanmai

これは エイリアス と呼ばれ、信号処理の基本的な問題です。サンプルレートを上げることで少し改善できます。4mの範囲は2mの範囲で少し短いです。 10mの範囲を試してください。

たとえば、1515722220で実行されたクエリでは、580 @ 1515722085.194および[email protected]のサンプルのみが表示されます。これは2分で1の増加で、4分で推定すると2の増加になります-これは予想どおりです。

メトリックベースの監視システムには同様のアーティファクトがありますが、100%の精度が必要な場合はログが必要です。

15
brian-brazil

increase()は、実際の増加量を常に(約)2倍に設定します。

その理由は(現在実装されているとおり):

  1. increase()は、(観察したとおり)rate()の構文糖です。つまり、rate()によって返される値に、範囲内の秒数を掛けたものです指定。あなたの場合、それはrate() * 240です。
  2. rate()は、計算に外挿を使用します。ほとんどの場合、4分の範囲では、正確に2分の間隔で正確に2つのデータポイントが返されます。次に、レートは最後と最初の差(つまり、2ポイント)を2ポイントの時間差(99.99%のケースでは約120秒)で乗算し、要求された範囲(正確には240秒)を掛けて計算されます。 )。したがって、2ポイント間の増加がゼロの場合、レートはゼロです。 2点間の増加が_1.0_の場合、計算されたrate()は_2.0 / 240_に近くなり、その結果、increase()は_2.0_。

このアプローチは、カウンターがスムーズに増加する場合にほとんど正常に機能します(たとえば、2分ごとのサインアップの数が固定されている場合など)。ただし、(サインアップカウンターがそうであるように)めったに増加しないカウンターまたは(CPU使用率のような)スパイクカウンターを使用すると、奇妙な過大評価(表示されている2の増加など)が発生します。

基本的に、Prometheusの実装をリバースエンジニアリングして、_(requested_range - scrape interval)_で乗算し、_requested_range_で除算することで、実際の増加を(非常に近い値で)取得できます。

あなたの場合、これは

_increase(signups_count[4m]) * (240 - 120) / 240
_

または、もっと簡潔に言えば、

_increase(signups_count[4m]) / 2
_

範囲の長さとスクレイプ間隔の両方に注意する必要がありますが、ほとんどの場合、「1の場合は1、2の場合は2」という希望どおりの結果が得られます。場合によっては_1.01_ではなく_1.0_が表示されます。これは、スクレイプが120秒間隔ではなく119秒だったためです。場合によっては、評価がスクレイプと密接に一致している場合、境界上のいくつかのポイントが含まれている可能性があります。データポイントの計算ではありませんが、それでも_2.0_よりは良い答えです。

4