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'))
上記の流入クエリで何が間違っているのかについてのアイデアはありますか?
変化しない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)
微分間隔が1s
の2s
バケットに物事をグループ化する場合を考えてみます。私たちが見るべき結果は
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
の微分間隔を指定する場合、要求しているのは、2s
1s
バケットのGROUP BY
変化率です。
微分間隔が2s
の2s
バケットの場合に同様の推論を適用すると、次のようになります。
0s-2s → 2s-4s
2*(5-1)/2 → 2*(11-5)/2
4 → 6
ここで求めているのは、2s
2s
バケットのGROUP BY
の変化率であり、最初の間隔では2s
の変化率は4
および2番目の間隔2s
の変化率は6
になります。
@ Michael-Desaは素晴らしい説明をしています。
その答えを、当社が関心を持っているかなり一般的な指標の解決策で補強したいと思います。「最大「1秒あたりの操作」とは何ですか」特定の測定フィールドの値?」.
当社の実例を使用します。
RDBMSから redis に大量のデータを送信します。そのデータを転送するとき、5つのカウンターを追跡します。
TipTrgUp
->ビジネストリガーによる更新(ストアドプロシージャ)TipTrgRm
->ビジネストリガーによる削除(ストアドプロシージャ)TipRprUp
->無人自動修復バッチプロセスによる更新TipRprRm
->無人の自動修復バッチプロセスによって削除しますTipDmpUp
->バルクダンププロセスによる更新これらのカウンターの現在の状態を1秒間隔(構成可能)でInfluxDBに送信するメトリックコレクターを作成しました。
これは便利な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のドキュメントでは簡単に見落とされがちです。
(@ Michael-Desaによって提案されているように)単純に1の解像度を使用すると、膨大な量のデータがinfluxdbからクライアントに転送されます。それはかなりうまく機能しますが(約10秒)、私たちには遅すぎます。
ただし、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)
_
これらの種類のメトリックに対する最終的な解決策(ただし、ライブビューが必要な場合のみ、サブクエリアプローチはアドホックグラフで正常に機能します)は、連続クエリを使用して真の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)
_
1の精度にズームインすると、グラフが同一になることがわかります。
これがお役に立てば幸いです、TW
ここでの問題は、Grafanaで表示している時間枠に応じて$__interval
の幅が変化することです。
一貫した結果を得る方法は、各間隔からサンプルを取得し(mean()
、median()
、またはmax()
はすべて同じように機能します)、derivative($__interval)
。そうすれば、ズームイン/ズームアウトすると、微分が間隔の長さに一致するように変化します。
したがって、クエリは次のようになります。
SELECT derivative(mean("mem.gc.count"), $__interval) FROM "influxdb"
WHERE $timeFilter GROUP BY time($__interval) fill(null)