メモ-PrometheusにおけるMetricsのData Type
最近、EKS(Elastic Kubernetes Service)を使ってMSA(Micro Service Architecture)でシステムを運用する場面に出くわして、Observabilityを割と真剣に勉強している
このObservability(=可観測性)については、勉強し始めたらかなり面白くてまた別の機会にまとめようと思っている
今回は、Observabilityの3本柱(Log, Metrics, Trace)のうちの一つであるMetricsを支えるPrometheusについて、
メトリクスのデータタイプがいまいち腹落ちしなかったので、自分の言葉(公式サイトの翻訳)でメモを残しておこうと思う
Prometheusについて(超ざっくり)
RPSやレイテンシ、CPU使用率、Podの死活状態など、サービスとかサーバーの各種メトリクスを集めるためのツール
Kubernetesを使ってMSAでシステムを構築する際、Metricsを実現するためのツールとして現状は デファクトの地位にいる認識(同列でDatadog?)
実際は、Prometheusで取得したメトリクスを可視化するツールとしてGrafanaと一緒に使われることが多くて、Prometheus自体のメトリクス可視化ツールはあまり使われず、Prometheusはあくまで時系列データベースのような形で使われてるイメージ
ちなみに・・・
「現状は」と書いたのは、3, 4年くらい前から上で挙げたObservabilityを向上させるぜという話題は出ていたけど、去年とか今年に入ったあたりから、Observabilityを可能にするための取組みが主要Cloud Serviceで急加速してる印象で、Kubernetesもマネージドサービスで運用するのが主流になっているのでこの状況はいずれ崩れるんじゃないかなーと思ってる
事実、GCPが提供しているAnthosなんかは、デフォルトでCloud LoggingとCloud Monitoringをサポートして、Observabilityの実現を容易にしてくれてるし・・・
メトリクスのデータタイプ
とても話が逸れてしまいましたが、本題のPrometheusのメトリクスのデータタイプについて
Prometheusには用途に合わせて4つのデータタイプが用意されていて、これらから目的の形にデータを加工して可視化することができる
Counter
再起動などのタイミングに0にリセットされることはあっても、単調増加するという性質は変わらない
減少しうる値などには使用できない
Gauge
気温やメモリ使用率など、単一の上下する値のためのメトリクス
Histogram
観測値をサンプリングし、設定可能なバケット毎にカウントする
全観測値の合計も分かる
basenameという名前のHistogramを用意したとすると、
basename_backet{le="<upper inclusive bound>"} : 指定したバケットまでの、バケット毎の累積の数 basename_sum : 全観測値の合計 basename_count : 観測されたイベントの回数 (これは、basename_bucket{le="+Inf"}としているのと同様)
quantileを計算したい場合は、histogram_quantile()を使用することで計算可能
注意点としては、basename_bucketは累積的ヒストグラム(cumulative histogram=累積度数図)であるということ
-> 普段目にするヒストグラムとは異なる
-> Wikiがちゃんとまとめてくれてる
Bucketを採用していることで、Apdex scoreを計算することができる
-> Apdexを計算したい場合はHistogram1択
Summary
Histogram同様、観測値をサンプリングする
Histogram同様、全観測値の合計や観測回数を取得することもできる
Summaryの特徴的な点は、Sliding Time Window方式で、設定したquantileを計算できるということ
basenameという名前のSummaryを用意したとすると、
basename{quantile="φ"} : φ-quantileの観測イベント basename_sum : 全観測値の合計 basename_count : 観測されたイベントの回数
HistogramとSummary
共通点
両方とも累積的である点で、本質的にはCounterと同じ
ただし、負数を扱うこともできる点でCounterとは異なる
HistogramやSummaryが使われる典型的な場面は、Latencyやレスポンスのサイズのメトリクスを取得するためだが、これらは負数にはならないので一旦負数のことは考えない
負数を取らない限りにおいて、prometheusのrate関数を使用することができるようになる相違点
Histogramは、histogram_quantileを使ってサーバー側で計算する
Summaryは、クライアント側で計算した結果をサーバーに送る
使い分け
Histogram
良い点
Histogramは、promQLを使って柔軟にデータを取得できる
クライアント(実際にサービスが動いているアプリケーションサーバーやウェブサーバー)で処理をする必要がない良くない点
いくつのBucketを、いくつ間隔で用意するか、正しく設定できないと有効でない
5つをBucketを0.01秒ごとに用意すると0.05秒以上は全てまとめてカウントされるし、逆に5つのBucketを1秒ごとに用意すると、1秒以下は全てまとめてカウントされる
このバランスをどこで取れるかを、事前にある程度分かっていないとうまくメトリクスを取れない
Summary
良い点
クライアント側で計算できるので、サーバーの負荷はかからない良くない点
Summaryは事前にquantileがわかっていないと、後から変更する場合コストが高い
特にオートスケールなど、複数のインスタンスで同じサービスが動いている場合は、個々のクライアントで計算してprometheusサーバーに送り集約する形だと意味がない、もしくはほとんど意味がわからない
(「個々のインスタンス」というよりは「同じサービス全体として」のメトリクスを取りたい)
結論
SummaryでできるがHistogramでできないということは基本的にないし、メリデメを比較しても「使い分け」というよりは、特別必要がない限り基本的にHistogramを使う方が良いと思う