web-dev-qa-db-ja.com

influxdb non_negative_derivativeで一貫した値を取得するにはどうすればよいですか?

Influxdbでgrafanaを使用して、カウンターである値の1秒あたりのレートを表示しようとしています。 non_negative_derivative(1s)関数を使用すると、グラファナビューの時間幅に応じてレートの値が劇的に変化するように見えます。 lastセレクターを使用しています(ただし、カウンターであるため、同じ値であるmaxを使用することもできます)。

具体的には、次のものを使用しています。

SELECT non_negative_derivative(last("my_counter"), 1s) FROM ...

influxdb docs non-negative-derivative によると:

InfluxDBは、時系列のフィールド値の差を計算し、それらの結果を単位あたりの変化率に変換します。

つまり、私にとっては、値は単位あたりの変化率である必要があるため、時間ビューを展開するときに、特定のポイントの値がそれほど変化しないことを意味します。 -)(上記のクエリ例では1秒)。

グラファイトでは、特定のperSecond関数があり、これははるかにうまく機能します。

perSecond(consolidateBy(my_counter, 'max'))

上記の流入クエリで何が間違っているのかについてのアイデアはありますか?

11
Ben

変化しない1秒あたりの結果が必要な場合は、GROUP BY time(1s)が必要です。これにより、正確なperSecond結果が得られます。

次の例を考えてみましょう。

毎秒のカウンターの値が次のように変化するとします。

0s → 1s → 2s → 3s → 4s
1  → 2  → 5  → 8  → 11

上記のシーケンスをグループ化する方法に応じて、異なる結果が表示されます。

物事を2sバケットにグループ化する場合を考えてみましょう。

 0s-2s   →    2s-4s
(5-1)/2  →  (11-5)/2
   2     →      3

1sバケット

 0s-1s  →  1s-2s  →  2s-3s  →  3s-4s
(2-1)/1 → (5-2)/1 → (8-5)/1 → (11-8)/1
   1    →    3    →    3    →    3

アドレッシング

つまり、時間ビューを展開するときに、特定のポイントの値がそれほど変化しないようにする必要があります。これは、値が単位あたりの変化率(上記のクエリ例では1秒)である必要があるためです。

rate of change per unitは、GROUP BY時間単位に依存しない、正規化係数です。微分間隔を2sに変更するときに前の例を解釈すると、いくつかの洞察が得られる場合があります。

正確な方程式は

∆y/(∆x/tu)

微分間隔が1s2sバケットに物事をグループ化する場合を考えてみます。私たちが見るべき結果は

 0s-1s    →  1s-2s    →  2s-3s    →  3s-4s
2*(2-1)/1 → 2*(5-2)/1 → 2*(8-5)/1 → (11-8)/1
   2      →    6      →    6      →    6

これは少し奇妙に思えるかもしれませんが、これが何を言っているかを考えると、それは理にかなっているはずです。 2sの微分間隔を指定する場合、要求しているのは、2s1sバケットのGROUP BY変化率です。

微分間隔が2s2sバケットの場合に同様の推論を適用すると、次のようになります。

 0s-2s     →    2s-4s
2*(5-1)/2  →  2*(11-5)/2
   4       →      6

ここで求めているのは、2s2sバケットのGROUP BYの変化率であり、最初の間隔では2sの変化率は4および2番目の間隔2sの変化率は6になります。

22
Michael Desa

@ Michael-Desaは素晴らしい説明をしています。

その答えを、当社が関心を持っているかなり一般的な指標の解決策で補強したいと思います。「最大「1秒あたりの操作」とは何ですか」特定の測定フィールドの値?」.

当社の実例を使用します。

シナリオの背景

RDBMSから redis に大量のデータを送信します。そのデータを転送するとき、5つのカウンターを追跡します。

  1. TipTrgUp->ビジネストリガーによる更新(ストアドプロシージャ)
  2. TipTrgRm->ビジネストリガーによる削除(ストアドプロシージャ)
  3. TipRprUp->無人自動修復バッチプロセスによる更新
  4. TipRprRm->無人の自動修復バッチプロセスによって削除します
  5. TipDmpUp->バルクダンププロセスによる更新

これらのカウンターの現在の状態を1秒間隔(構成可能)でInfluxDBに送信するメトリックコレクターを作成しました。

グラファナグラフ1:低解像度、真の最大操作なし

これは便利なgrafanaクエリですが、ズームアウトしたときに実際の最大opsが表示されません(特別なダンプやメンテナンスが行われていない通常の営業日には約500 opsになります-それ以外の場合は、数千):

_SELECT
    non_negative_derivative(max(TipTrgUp),1s) AS "update/TipTrgUp"
   ,non_negative_derivative(max(TipTrgRm),1s) AS "remove/TipTrgRm"
   ,non_negative_derivative(max(TipRprUp),1s) AS "autorepair-up/TipRprUp"
   ,non_negative_derivative(max(TipRprRm),1s) AS "autorepair-rm/TipRprRm"
   ,non_negative_derivative(max(TipDmpUp),1s) AS "dump/TipDmpUp"
FROM "$rp"."redis_flux_-transid-d-s"
WHERE
    Host =~ /$server$/
    AND $timeFilter
GROUP BY time($interval),* fill(null)
_

補足:_$rp_は、グラファナでテンプレート化された保持ポリシーの名前です。 CQを使用して、より長い期間の保持ポリシーにダウンサンプリングします。派生パラメーターとして_1s_にも注意してください。GROUPBYを使用する場合のデフォルトが異なるため、これが必要です。これは、InfluxDBのドキュメントでは簡単に見落とされがちです。

24時間で見たグラフは、次のようになります。 enter image description here

(@ Michael-Desaによって提案されているように)単純に1の解像度を使用すると、膨大な量のデータがinfluxdbからクライアントに転送されます。それはかなりうまく機能しますが(約10秒)、私たちには遅すぎます。

グラファナグラフ2:低解像度と高解像度、真の最大ops、パフォーマンスの低下

ただし、subqueriesを使用して、このグラフに真のmaxopsを追加できます。これは、わずかな改善です。クライアントに転送されるデータははるかに少なくなりますが、InfluxDBサーバーは多くの数の処理を行う必要があります。シリーズB(エイリアスの前にmaxopsが付いています):

_SELECT
    max(subTipTrgUp) AS maxopsTipTrgUp
   ,max(subTipTrgRm) AS maxopsTipTrgRm
   ,max(subTipRprUp) AS maxopsRprUp
   ,max(subTipRprRm) AS maxopsTipRprRm
   ,max(subTipDmpUp) AS maxopsTipDmpUp
FROM (
    SELECT
        non_negative_derivative(max(TipTrgUp),1s) AS subTipTrgUp
       ,non_negative_derivative(max(TipTrgRm),1s) AS subTipTrgRm
       ,non_negative_derivative(max(TipRprUp),1s) AS subTipRprUp
       ,non_negative_derivative(max(TipRprRm),1s) AS subTipRprRm
       ,non_negative_derivative(max(TipDmpUp),1s) AS subTipDmpUp
    FROM "$rp"."redis_flux_-transid-d-s"
    WHERE
        Host =~ /$server$/
        AND $timeFilter
    GROUP BY time(1s),* fill(null)
)
WHERE $timeFilter
GROUP BY time($interval),* fill(null)
_

与える: enter image description here

グラファナグラフ3:低解像度と高解像度、真の最大ops、高性能、CQによる事前計算

これらの種類のメトリックに対する最終的な解決策(ただし、ライブビューが必要な場合のみ、サブクエリアプローチはアドホックグラフで正常に機能します)は、連続クエリを使用して真のmaxopsを事前計算することです。次のようなCQを生成します。

_CREATE CONTINUOUS QUERY "redis_flux_-transid-d-s.maxops.1s"
ON telegraf
BEGIN
    SELECT
        non_negative_derivative(max(TipTrgUp),1s) AS TipTrgUp
       ,non_negative_derivative(max(TipTrgRm),1s) AS TipTrgRm
       ,non_negative_derivative(max(TipRprUp),1s) AS TipRprUp
       ,non_negative_derivative(max(TipRprRm),1s) AS TipRprRm
       ,non_negative_derivative(max(TipDmpUp),1s) AS TipDmpUp
    INTO telegraf.A."redis_flux_-transid-d-s.maxops"
    FROM telegraf.A."redis_flux_-transid-d-s"
    GROUP BY time(1s),*
END
_

これ以降、これらのmaxops測定値をグラファナで使用するのは簡単です。保持期間の長いRPにダウンサンプリングする場合は、セレクター関数としてmax()を再度使用します。

シリーズB(エイリアスに_.maxops_が追加されています)

_SELECT
    max(TipTrgUp) AS "update/TipTrgUp.maxops"
   ,max(TipTrgRm) AS "remove/TipTrgRm.maxops"
   ,max(TipRprUp) as "autorepair-up/TipRprUp.maxops"
   ,max(TipRprRm) as "autorepair-rm/TipRprRm.maxops"
   ,max(TipDmpUp) as "dump/TipDmpUp.maxops"
FROM "$rp"."redis_flux_-transid-d-s.maxops"
WHERE
    Host =~ /$server$/
    AND $timeFilter
GROUP BY time($interval),* fill(null)
_

与える: enter image description here

1の精度にズームインすると、グラフが同一になることがわかります。 enter image description here

これがお役に立てば幸いです、TW

6
Tw Bert

ここでの問題は、Grafanaで表示している時間枠に応じて$__intervalの幅が変化することです。

一貫した結果を得る方法は、各間隔からサンプルを取得し(mean()median()、またはmax()はすべて同じように機能します)、derivative($__interval)。そうすれば、ズームイン/ズームアウトすると、微分が間隔の長さに一致するように変化します。

したがって、クエリは次のようになります。

SELECT derivative(mean("mem.gc.count"), $__interval) FROM "influxdb"
WHERE $timeFilter GROUP BY time($__interval) fill(null)
1
Dave