1. ホーム
  2. java

DropWizard メトリクス・メーターとタイマーの比較

2023-10-18 18:52:25

質問

私は DropWizard メトリクス・ライブラリ (旧 Coda Hale メトリクス) を学んでいるのですが、どのような場合に MetersTimers . ドキュメントによると

メーターです。 メーターは、一連のイベントが発生する速度を測定する。

とします。

<ブロッククオート

タイマーです。 タイマーは基本的に、ある種のイベントの持続時間のヒストグラムであり、その発生率のメーターである。

これらの定義に基づくと、私はこれらの違いを識別することができません。私を混乱させているのは Timer が、私が期待するような使われ方をしていないことです。私にとっては Timer は単なるタイマーです。 start()stop() . しかし、どうやら Timers はイベントの発生率も捉えているようで、まるで Meters のつま先を踏んでいるように感じられます。

それぞれのコンポーネントが出力するものの例を見ることができれば、いつ/どこでこれらのいずれかを使用するかを理解する助けになるかもしれません。

どのように解決するのですか?

あなたが混乱している理由のひとつは、DW メトリクス タイマー IS であり、特に DW Metrics Meter です。

メーターは、Hz (イベント/秒) で測定される速度にのみ関係しています。各メーターは、4つ(?)の異なるメトリクスが公開される結果となります。

  • Metrics が開始されてからの平均レート。
  • 1 分、5 分、15 分のローリング平均レート

DW Metrics は、各呼び出しのウォールタイムを、あなたが与えた値とともに自動的に記録し、これらを使用して、値が増加している割合を計算します。

Meter getRequests = registry.meter("some-operation.operations")
getRequests.mark() //resets the value, e.g. sets it to 0
int numberOfOps = doSomeNumberOfOperations() //takes 10 seconds, returns 333
getRequests.mark(numberOfOps) //sets the value to number of ops.

333回の操作が発生し、mark()の2回の呼び出しの間の時間が10秒であったため、レートは33.3Hzであると予想されます。

Timerは上記の4つのメトリクスを計算し(各Timer.Contextを1つのイベントとみなします)、それにいくつかの追加のメトリクスを追加します。

  • イベント数のカウント
  • Metrics の開始以降に見た最小、平均、最大の継続時間
  • 標準偏差
  • 50%、97%、98%、99%、99.95%に分布する継続時間を記録したヒストグラム。

各タイマーについて、合計で約 15 のメトリックが報告されます。

要するに : タイマーは多くのメトリクスを報告し、理解するのが難しいかもしれませんが、いったん理解すれば、スパイキーな動作を発見するための非常に強力な方法です。


実際、2 つのポイント間に費やされた時間を収集するだけでは、非常に有用な測定基準ではありません。例えば、次のようなコードのブロックがあるとします。

Timer timer = registry.timer("costly-operation.service-time")
Timer.Context context = timer.time()
costlyOperation() //service time 10 ms
context.stop()

と仮定してみましょう。 costlyOperation() が一定のコスト、一定の負荷を持ち、シングルスレッドで動作しているとします。1 分の報告期間内に、この操作の時間を 6000 回計る必要があります。明らかに、6000 回の配線上の実際のサービス時間を報告することはありません。その代わりに、希望する報告ウィンドウに合うようにこれらの操作すべてを要約する何らかの方法が必要です。DW MetricsのTimerは、1分(報告期間)に1回、自動的にこれを行います。5 分後、メトリック レジストリはレポートを作成します。

  • 100 (イベント/秒) のレート
  • 1 分間の平均レートは 100
  • 5 分間の平均レート 100
  • 30000 のカウント (見たイベントの合計)
  • 最大 10 (ミリ秒)
  • 最小値 10
  • 10 の平均値
  • 50 パーセンタイル (p50) 値 10
  • 99.9パーセンタイル (p999) 値は10です。

さて、時折、オペレーションが完全にレールから外れてしまい、長期間ブロックされる期間に入ったと考えましょう。

Timer timer = registry.timer("costly-operation.service-time")
Timer.Context context = timer.time()
costlyOperation() //takes 10 ms usually, but once every 1000 times spikes to 1000 ms
context.stop()

1分間の収集期間では、1000回実行するごとに時間がかかるため、6000回未満の実行を見ることになります。約 5505 回に計算されます。最初の 1 分 (合計 6 分のシステム時間) の後、私たちは今、以下を見るでしょう。

  • 平均レート 98 (イベント/秒)
  • 1 分間の平均レート 91.75
  • 5 分間の平均レート 98.35
  • 35505 のカウント (見たイベントの合計)
  • 最大継続時間 1000 (ms)
  • 最小継続時間 10
  • 平均持続時間 10.13
  • 50 パーセンタイル (p50) 値 10
  • 99.9パーセンタイル(p999)値1000

これをグラフにすると、ほとんどのリクエスト (p50、p75、p99 など) は 10ms で完了していますが、1000 のうち 1 つのリクエスト (p99) は 1s で完了していることがわかると思います。これは、平均レートのわずかな減少 (約 2%) と 1 分間平均の大幅な減少 (約 9%) とも見られるでしょう。

時間の平均値 (レートまたは期間) を見るだけなら、これらのスパイクを見つけることはできません。同様に、最大値を知るだけでは、その最大値がどれくらいの頻度で発生するのかが分からないため、役に立ちません。これが、ヒストグラムがパフォーマンスを追跡するための強力なツールであり、DW Metrics のタイマーがレートとヒストグラムの両方を公開する理由です。