このページはPrometheus公式ドキュメント和訳+αの一部です。
Why are Prometheus histograms cumulative?
なぜヒストグラムのバケットが、単に各バケットに入ったイベントのカウンターではないのか考えたことはあるだろうか?
例えば、レイテンシーを記録するためのデフォルトのバケットのヒストグラムがあり、0.04s、0.2s、0.3s、1s、5sのサイズのイベントを観測したとする。 テキスト形式の出力は以下のようになるだろう。
# HELP example_latency_seconds Some help text # TYPE example_latency_seconds histogram example_latency_seconds_bucket{le="0.005"} 0.0 example_latency_seconds_bucket{le="0.01"} 0.0 example_latency_seconds_bucket{le="0.025"} 0.0 example_latency_seconds_bucket{le="0.05"} 1.0 example_latency_seconds_bucket{le="0.075"} 1.0 example_latency_seconds_bucket{le="0.1"} 1.0 example_latency_seconds_bucket{le="0.25"} 2.0 example_latency_seconds_bucket{le="0.5"} 3.0 example_latency_seconds_bucket{le="0.75"} 3.0 example_latency_seconds_bucket{le="1.0"} 4.0 example_latency_seconds_bucket{le="2.5"} 4.0 example_latency_seconds_bucket{le="5.0"} 5.0 example_latency_seconds_bucket{le="7.5"} 5.0 example_latency_seconds_bucket{le="10.0"} 5.0 example_latency_seconds_bucket{le="+Inf"} 5.0 example_latency_seconds_count 5.0 example_latency_seconds_sum 6.54
0.05のバケットには、期待通りに、1つのサンプルがある。 0.25のバケットには、0.1 < x <= 0.25の範囲に1つのサンプルしかないにも関わらず、2つのサンプルがある。 これは、le
がless than or equal toの略であり、各バケットはそれ以下のサンプルを含んでいるからである。 したがって、+Infのバケットは、サンプル数の合計(_count
と等しい)となる。
このことが、ヒストグラムが累積的でないと期待している人を驚かせることがある。 では、なぜ、直感的な非累積的なヒストグラムの代わりに、累積的なヒストグラムを使うのか?
The answer is operational. ラベルがあれば常に要素数を一緒に考えなければならない。 ヒストグラムは、デフォルトで、バケットの数が10である。 もし、ヒストグラムにさらにラベルを追加したり、さらにバケットを追加すると、ヒストグラムのコストがかなり高くなる可能性がある。 ヒストグラムが累積的であるということは、Prometheusに取り込む際に、いくつかのバケットをdropすることができるということである。 (いくらか不正確だが)分位数の計算を可能としつつPrometheusのコストを減らすことになる。 これによって、アプリケーションのコードをバケット数が減るように修正するための時間を稼ぐことができる。
例えば、100ms以下のバケットを全てなくしたいとすると、以下のリラベルの設定が利用できるだろう。
scrape_configs: - job_name: 'my_job' static_configs: - targets: - my_target:1234 metric_relabel_configs: - source_labels: [ __name__, le ] regex: 'example_latency_seconds_bucket;(0\.0.*)' action: drop
好きなだけ多くのまたは少しのバケットをdropすることができるが、+Infのバケットはhistogram_quantile
のために必要である。
ヒストグラムに_sum
と_count
があるのは、ヒストグラムの要素数が多くなり過ぎる可能性があるためでもある。 もし、全てのバケットの時系列をdropしても、その2つの時系列だけから平均レイテンシーを計算することができる。
さらに、この方法のおかげで、あるバケット以下のイベントの比率を計算するのも簡単になる。 例えば、1s以下のイベントの比率は以下の式で計算できる。
example_latency_seconds_bucket{le="1.0"} / ignoring (le) example_latency_seconds_bucket{le="+Inf"}
翻訳元
おすすめ書籍

入門 Prometheus ―インフラとアプリケーションのパフォーマンスモニタリング
- 作者: Brian Brazil,須田一輝,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2019/05/18
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る

SRE サイトリライアビリティエンジニアリング ―Googleの信頼性を支えるエンジニアリングチーム
- 作者: 澤田武男,関根達夫,細川一茂,矢吹大輔,Betsy Beyer,Chris Jones,Jennifer Petoff,Niall Richard Murphy,Sky株式会社玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2017/08/12
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る