2015-06-22 25 views
45

Ich lerne die DropWizard Metrics library (früher Coda Hale Metriken) und ich bin verwirrt, wenn ich Meters vs Timers verwenden sollte. Nach der Dokumentation:DropWizard Metrics Meter vs Timer

Meter: A Meter misst die Rate, mit der eine Reihe von Ereignissen

auftreten und:

Timer: Ein Timer ist im Grunde ein Histogramm der Dauer eines Ereignistyps und eines Zählers der Häufigkeit seines Auftretens

Basierend auf diesen Definitionen kann ich den Unterschied zwischen diesen nicht erkennen. Was mich verwirrt ist, dass Timer nicht so verwendet wird, wie ich es erwartet hätte. Für mich ist Timer genau das: ein Timer; Es sollte die Zeitdifferenz zwischen einer start() und stop() messen. Aber es scheint, dass Timers auch erfassen Raten, bei denen Ereignisse auftreten, die sich anfühlt, als ob sie auf Meters' Zehen treten.

Wenn ich ein Beispiel sehen könnte, was jede Komponente ausgibt, die mir helfen könnte, zu verstehen, wann/wo einer von diesen verwendet werden soll.

Antwort

99

Sie sind teilweise verwirrt, weil ein DW Metrics Timer IS, unter anderem ein DW Metrics Meter ist.

Ein Messgerät befasst sich ausschließlich mit Raten, gemessen in Hz (Ereignisse pro Sekunde). (?) Jeder Meter ergibt 4 verschiedene Kennzahlen veröffentlicht:

  • ein Mittelwert (Durchschnitt) Rate seit Metrics wurde gestartet
  • 1, 5 und 15 Minuten Roll bedeuten Raten

Sie verwenden ein Meter durch Aufzeichnen eines Wertes an verschiedenen Punkten in Ihrem Code - DW Metrics zeichnet automatisch die Wandzeit jedes Anrufs zusammen mit dem Wert auf, den Sie ihm gegeben haben, und verwendet diese, um die Rate zu berechnen, mit der dieser Wert zunimmt:

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. 

Wir würden erwarten, dass unsere Raten 33,3 Hz betragen, da 333 Operationen aufgetreten sind und die Zeit zwischen den beiden Aufrufen von mark() 10 Sekunden betrug.

A Timer diese über 4 Metriken berechnet (jeweils Timer.Context Berücksichtigung eines Ereignisses sein), und fügt sie eine Reihe von zusätzlichen Messdaten:

  • eine Zählung der Anzahl der Ereignisse
  • min, bedeuten und max Dauern seit Beginn der Metrics
  • Standardabweichung
  • a gesehen „Histogramm“, die Dauer auf der 50., 97., 98., 99. und 99.95 Perzentile
verteilt Aufzeichnungs

Es gibt ungefähr 15 Gesamtmetriken für jeden Timer.

In Kürze: Timer melden eine Menge Metriken, und sie können schwierig zu verstehen sein, aber sobald Sie dies tun, sind sie eine ziemlich leistungsfähige Möglichkeit, spike Verhalten zu erkennen.

Fakt ist, nur die Zeit zwischen zwei Punkten zu sammeln ist keine besonders nützliche Kennzahl. Bedenken Sie: Sie einen Code-Block wie diese:

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

Lassen Sie sich diese costlyOperation annehmen() eine konstant Kosten, konstante Last und arbeitet auf einem einzigen Thread. Innerhalb einer 1-minütigen Berichtsperiode sollten wir davon ausgehen, dass diese Operation 6000 Mal durchgeführt wird. Natürlich werden wir die tatsächliche Servicezeit nicht über den wire 6000x berichten - stattdessen müssen wir alle diese Vorgänge zusammenfassen, damit sie in unser gewünschtes Berichtsfenster passen. DW Metrics 'Timer erledigt dies automatisch für uns, einmal pro Minute (unsere Berichtsperiode). Nach 5 Minuten würde unsere Metriken Registrierung Berichterstattung werden:

  • eine Rate von 100 (Ereignissen pro Sekunde)
  • 1 Minute mittlere Rate von 100
  • 5 Minuten mittlere Rate von 100
  • einer Zahl von 30000 (Gesamtereignissen zu sehen)
  • ein Maximum von 10 (ms)
  • eine Minute von 10
  • ein Mittelwert von 10
  • ein 50. Perzentil (p50) Wert von 10
  • ein 99.9th Perzentil (P999) Wert von 10

Nun lassen Sie uns betrachten wir eine Zeit geben, wo hin und wieder unser Betrieb vollständig aus den Schienen und Blöcke für eine geht längere Zeit:

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() 

über 1 Minute Sammelperiode, würden wir jetzt weniger als 6000 Hinrichtung sehen, wie jede 1000. Ausführung länger dauert. Ausarbeitet bis etwa 5505. Nach der ersten Minute (6 Minuten Gesamtsystemzeit) dies würden wir jetzt sehen:

  • eine mittlere Geschwindigkeit von 98 (Ereignissen pro Sekunde)
  • 1 Minute mittlere Rate von 91,75
  • 5 Minuten mit mittlerer Rate von 98,35
  • eine Zählung von 35505 (Gesamtereignissen zu sehen)
  • a max Dauer von 1000 (ms)
  • min eine Dauer von 10
  • eine mittleren Dauer von 10 .13
  • ein 50. Perzentil (p50) Wert von 10
  • ein 99.9th Perzentil (P999) Wert von 1000

Wenn Sie diese grafisch dargestellt, die Sie sehen würden, dass die meisten Anfragen (die p50, p75 , p99 usw.) wurden in 10 ms abgeschlossen, aber eine Anforderung von 1000 (p99) wurde in 1s abgeschlossen. Dies würde auch als eine leichte Verringerung der Durchschnittsrate (etwa 2%) und eine beträchtliche Verringerung des Mittelwerts von 1 Minute (fast 9%) angesehen werden.

Wenn Sie nur die Überzeit (entweder Rate oder Dauer) betrachten, werden Sie niemals diese Spikes entdecken - sie werden in das Hintergrundrauschen gezogen, wenn sie mit vielen erfolgreichen Operationen gemittelt werden. Genauso ist es nicht hilfreich, nur das Maximum zu kennen, weil es nicht sagt, wie oft das Maximum auftritt. Aus diesem Grund sind Histogramme ein leistungsfähiges Werkzeug, um die Performance zu verfolgen, und warum DW Metrics 'Timer sowohl eine Rate als auch ein Histogramm veröffentlicht.

+1

Eine nette zusätzliche Information ist [hier] enthalten (http://metrics.dropwizard.io/3.1.0/manual/core/#histograms). Timer verwenden standardmäßig einen exponentiell abklingenden Speicher. Das bedeutet, dass Sie Daten aus den letzten 5 Minuten mit einer Tendenz zu neueren Daten für Ihre Histogramm-Werte sehen. – markdsievers

+0

Gibt es eine Möglichkeit, die Ausführungszeit jedes Mal zu erhalten, wenn ein Codeblock ausgeführt wird? Ich brauche das, abgesehen von den durchschnittlichen Raten, Durchschnittsraten und anderem. Ist das möglich? – mayooran

+0

Wenn Sie lediglich die Servicezeit für jede Ausführung eines Codeblocks messen und protokollieren möchten, ist dies für eine Metrikaggregationsbibliothek nicht wirklich der Fall. Der "Reservoir", in dem die Metriken gespeichert sind, speichert wahrscheinlich nicht genügend Kontext für Ihre Bedürfnisse. Glücklicherweise ist dies ein Problem, das Sie mit einfacher Protokollierung oder einem VM-Instrumentierungstool wie YourKit leicht lösen können. –