Grafana Mimir 入門
以前の記事で AWS の Amazon Managed Service for Prometheus について触れました。Amazon Managed Service for Prometheus は裏側で Cortex という OSS が利用されているとのことで、Cortex について調べたところ Grafana Mimir というものが登場していることがわかりました。
Grafana Labs によれば Grafana Mimir は Cortex の後継となるもので、スケーラビリティとパフォーマンスを向上したものとのことです。
今回 Grafana Mimir がどんなものか試してみたので紹介したいと思います。
Grafana Mimir の概要
Grafana Mimir は Amazon Managed Service for Prometheus と同じように、Prometheus が収集したメトリクスを長期間保管するためのツールです。Grafana Mimir は Prometheus からメトリクスデータを受け取り、定期的にデータを S3 などの外部ストレージサービスに保管します。また、Grafana などから Grafana Mimir に対してメトリクスデータをクエリすることもできます。
ローカル環境での起動
まずはチュートリアルにあるように、ローカル PC 上の docker で動かしてみます。
$ git clone https://github.com/grafana/mimir.git
$ cd docs/sources/tutorials/play-with-grafana-mimir/
$ docker compose up -d
...
⠿ Network play-with-grafana-mimir_default Created 0.1s
⠿ Volume "play-with-grafana-mimir_mimir-1-data" Created 0.0s
⠿ Volume "play-with-grafana-mimir_mimir-2-data" Created 0.0s
⠿ Volume "play-with-grafana-mimir_mimir-3-data" Created 0.0s
⠿ Volume "play-with-grafana-mimir_minio-data" Created 0.0s
⠿ Container play-with-grafana-mimir-grafana-1 Started 2.9s
⠿ Container play-with-grafana-mimir-minio-1 Started 2.8s
⠿ Container play-with-grafana-mimir-mimir-3-1 Started 2.8s
⠿ Container play-with-grafana-mimir-mimir-2-1 Started 2.9s
⠿ Container play-with-grafana-mimir-mimir-1-1 Started 2.5s
⠿ Container play-with-grafana-mimir-load-balancer-1 Started 4.0s
⠿ Container play-with-grafana-mimir-prometheus-1 Started 4.3s
チュートリアルのページやからもわかるとおり、下記のようなコンテナが起動されます。
Grafana × 1
Prometheus × 1
Mimir × 3
minio × 1
nginx × 1
ローカルのブラウザから http://localhost:9000 を開けば Grafana の画面が開きます。
Prometheus が Mimir のメトリクスを Mimir に転送していて(ややこしい)、デフォルトで Grafana 上には Mimir に関するダッシュボードが保存されています。
http://localhost:9009 を開けば Mimir の管理画面が開きます。
各コンポーネントのステータスや、Ingester というコンポーネントからメトリクスのデータを外部ストレージ(この場合は minio)に吐き出すためのトリガーがあります。
各リソース消費量はこんな感じ。
負荷については Prometheus を確認したところ、time series の数は 12000 くらいでした。scrape_interval が 5 秒なので Mimir には 1 秒あたり 2000 件のメトリクスデータが投入されています(上の方のダッシュボードにも 2K samples/sec と出ている)。
試しに Mimir のコンテナを一つ停止してみます。
tyrwzl@mbp2020 ~/g/g/p/certification_approval (refafctor/zoness/infra)> docker ps -a | grep mimir
2ec5e1e7c414 prom/prometheus:latest "/bin/prometheus --c…" 2 hours ago Up 2 hours 0.0.0.0:9090->9090/tcp play-with-grafana-mimir-prometheus-1
3c7825c5d58f nginx:latest "/docker-entrypoint.…" 2 hours ago Up 2 hours 80/tcp, 0.0.0.0:9009->9009/tcp play-with-grafana-mimir-load-balancer-1
0fb9460e6b02 grafana/mimir:latest "/bin/mimir -config.…" 2 hours ago Up 2 hours 8080/tcp play-with-grafana-mimir-mimir-3-1
baa3bb70f604 grafana/mimir:latest "/bin/mimir -config.…" 2 hours ago Up 2 hours 8080/tcp play-with-grafana-mimir-mimir-1-1
fda49dffce63 grafana/mimir:latest "/bin/mimir -config.…" 2 hours ago Up 2 hours 8080/tcp play-with-grafana-mimir-mimir-2-1
bd9105c4075f grafana/grafana:latest "/run.sh" 2 hours ago Up 2 hours 0.0.0.0:9000->3000/tcp play-with-grafana-mimir-grafana-1
3accbdfe65c5 minio/minio "sh -c 'mkdir -p /da…" 2 hours ago Up 2 hours 9000/tcp play-with-grafana-mimir-minio-1
tyrwzl@mbp2020 ~/g/g/p/certification_approval (refafctor/zoness/infra)> docker stop play-with-grafana-mimir-mimir-1-1
play-with-grafana-mimir-mimir-1-1
tyrwzl@mbp2020 ~/g/g/p/certification_approval (refafctor/zoness/infra)> docker ps -a | grep mimir
2ec5e1e7c414 prom/prometheus:latest "/bin/prometheus --c…" 2 hours ago Up 2 hours 0.0.0.0:9090->9090/tcp play-with-grafana-mimir-prometheus-1
3c7825c5d58f nginx:latest "/docker-entrypoint.…" 2 hours ago Up 2 hours 80/tcp, 0.0.0.0:9009->9009/tcp play-with-grafana-mimir-load-balancer-1
0fb9460e6b02 grafana/mimir:latest "/bin/mimir -config.…" 2 hours ago Up 2 hours 8080/tcp play-with-grafana-mimir-mimir-3-1
baa3bb70f604 grafana/mimir:latest "/bin/mimir -config.…" 2 hours ago Exited (0) 2 seconds ago play-with-grafana-mimir-mimir-1-1
fda49dffce63 grafana/mimir:latest "/bin/mimir -config.…" 2 hours ago Up 2 hours 8080/tcp play-with-grafana-mimir-mimir-2-1
bd9105c4075f grafana/grafana:latest "/run.sh" 2 hours ago Up 2 hours 0.0.0.0:9000->3000/tcp play-with-grafana-mimir-grafana-1
3accbdfe65c5 minio/minio "sh -c 'mkdir -p /da…" 2 hours ago Up 2 hours 9000/tcp play-with-grafana-mimir-minio-1
停止直後はクエリができなくなったのですが、数分以内には再度クエリができるようになりました。
次に mimir-1 の代わりに mimir-4 を追加してみます
tyrwzl@mbp2020 ~/w/m/d/s/t/play-with-grafana-mimir (main)> docker ps -a | grep mimir
c41a7b487fc2 grafana/mimir:latest "/bin/mimir -config.…" 39 seconds ago Up 38 seconds 8080/tcp play-with-grafana-mimir-mimir-4-1
2ec5e1e7c414 prom/prometheus:latest "/bin/prometheus --c…" 2 hours ago Up 2 hours 0.0.0.0:9090->9090/tcp play-with-grafana-mimir-prometheus-1
3c7825c5d58f nginx:latest "/docker-entrypoint.…" 2 hours ago Up 2 hours 80/tcp, 0.0.0.0:9009->9009/tcp play-with-grafana-mimir-load-balancer-1
0fb9460e6b02 grafana/mimir:latest "/bin/mimir -config.…" 2 hours ago Up 2 hours 8080/tcp play-with-grafana-mimir-mimir-3-1
baa3bb70f604 grafana/mimir:latest "/bin/mimir -config.…" 2 hours ago Exited (1) 25 seconds ago play-with-grafana-mimir-mimir-1-1
fda49dffce63 grafana/mimir:latest "/bin/mimir -config.…" 2 hours ago Up 2 hours 8080/tcp play-with-grafana-mimir-mimir-2-1
bd9105c4075f grafana/grafana:latest "/run.sh" 2 hours ago Up 2 hours 0.0.0.0:9000->3000/tcp play-with-grafana-mimir-grafana-1
3accbdfe65c5 minio/minio "sh -c 'mkdir -p /da…" 2 hours ago Up 2 hours 9000/tcp play-with-grafana-mimir-minio-1
その後、nginx の config を下記のようにして、新規作成した mimir-4 だけにリクエストが飛ぶようにしてもクエリすることができました。
events {
worker_connections 1024;
}
http {
upstream backend {
server mimir-4:8080 max_fails=1 fail_timeout=1s;
}
server {
listen 9009;
access_log /dev/null;
location / {
proxy_pass http://backend;
}
}
}
コンポーネント
Grafana Mimir には主に 6 つのコンポーネントから構成されおり、それぞれの役割が異なっています。
compactor: S3 などの外部ストレージに保存されたメトリクスデータの最適化、index の作成、retention に基づいた古いデータの削除
distributor: Prometheus から送信されるメトリクスデータのバリデーション、レート制限、HA Prometheus の重複排除、データをシャーディング & レプリケーション ingester へ送信
ingestor: Prometheus から送信されるメトリクスデータを S3 などの外部ストレージに保存する前の一時保管庫
querier: query-frontend に溜まっているキューからクエリジョブを取得してメトリクスデータを ingestor か store-gateway から引っ張ってくる
query-frontend: querier の前段に立ち、Grafana などから送信されたクエリを一度キューイングする
store-gateway:
下記画像のようにそれぞれのコンポーネントの役割はメトリクスデータの書き込み時か読み込み時かに分類することができます(ingester を除く)
query-frontend と querier を除くコンポーネントが
ローカル環境で確認したように、各コンポーネントをひとつのコンテナとして稼働(Monolithic mode)でき、また、別々のサービスとして稼働させる(Microservices mode)こともできます。
コスト
Grafana Mimir を動かすのに必要なリソースについてはこちらに記載があり、保存されるメトリクスの種類数、もしくは秒間クエリ数で求めることができます。
例えば、Grafana Mimir で管理するメトリクスの種類が 300000 件あり、Prometheus の scrape_interval が 15 秒、秒間クエリ数が 10 くらいであれば最低リソース数で動かすことができます。その場合必要なリソースは、
CPU: 11
Memory: 18.5 GB
Disk: 328 GB
くらいになります。AWS Fargate Ondemand の料金をもとにすると 1 月あたり $500 くらいになりそうです。一方で Amazon Managed Service for Prometheus の場合は、こちらのツールを利用してみると $ 1949 USD となりました。
Alertmanager や S3 のコストを考慮していないので正確な比較ではないですが、 Amazon Managed Service for Prometheus の月額料金が $500 くらいになるのが、メトリクスの種類が 70000 件くらいになったので、メトリクスの種類が 10 万件以上のワークロードでは Mimir のほうがコストを抑えられそうです。
まとめ
今回は Grafana Mimir 入門ということで、Grafana Mimir を実際に動かしてみたのと、それぞれのコンポーネントの役割、コストについて調べてみました。今回の記事では詳しく触れませんでしたが、長期保管するデータを複数台のコンテナで可用性を保ちつつパフォーマンスを出す仕組みを Grafana Mimir のアーキテクチャを調べる過程で触りだけでも理解することができました。
上記に関連して、POL の SRE に関する取り組みなど興味を持たれた場合は、お気軽にカジュアル面談にお申し込みください!