Prometheusの死と再生:OpenTelemetryという名の「最後のアーキテクチャ」
多くの現場では、未だにPrometheusを「単なるメトリクス収集ツール」として扱っている。それはあまりに勿体ない。Prometheusは強力だが、その「Pull型」という特性は、大規模分散システムにおいてボトルネックになりうる。
今、真にスケーラブルなオブザーバビリティを構築しようとするなら、Prometheusを「中心」に置くのではなく、「OpenTelemetry (OTel) Collectorをエッジに配置し、Prometheusを単なるストレージ・エンジンとして従属させる」という逆転の発想が必要だ。
本稿では、OTelとPrometheusの融合による、極限まで最適化された次世代メトリクス・パイプラインの設計思想を叩き込む。
—
1. なぜ「OTel Collector」を間に挟むのか?
Prometheusの`scrape_configs`に依存しすぎると、Kubernetesのクラスタサイズが拡大した瞬間に、Prometheusのメモリは食い尽くされ、スクレイプ間隔の揺らぎがSLI/SLOの計算を汚染し始める。
OTel Collectorの真価は「変換」と「ルーター」にある。
アプリケーションはすべてOTLPで送信し、Collectorで以下の処理を行う。
- 属性の正規化: サービス名や環境変数の揺らぎを、Collector側で正規化する(Prometheusに届く前にクリーンにする)。
- ヘッドベース・サンプリング: 高頻度メトリクスをPrometheusに送る前に、必要な粒度にダウンサンプリングする。
- サイドカーの排除: `scrape_configs`の自動検出に頼る運用を卒業し、アプリケーション側からPushさせることで、Service Discoveryの複雑さを解消する。
—
2. 究極のアーキテクチャ:OTLPからPrometheusへのパス
ここでは、OTel Collectorを`prometheusremotewrite`エクスポーターとして動かし、Prometheusを「Remote Writeを受信するだけのWrite-Ahead Log」として扱う設定を紹介する。
OTel Collector 設定 (pipeline.yaml)
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317 # アプリケーションからのメトリクス受付
processors:
batch:
# メモリ効率を最大化するためのバッチ処理調整
send_batch_size: 10000
timeout: 5s
exporters:
prometheusremotewrite:
endpoint: “http://prometheus-internal:9090/api/v1/write”
# 認証やリトライ戦略をここで定義し、Prometheus側の負荷を制御する
retry_on_failure:
enabled: true
initial_interval: 5s
service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [prometheusremotewrite]
エキスパートの知見:
ここで重要なのは `batch` プロセッサの設定だ。`send_batch_size` を上げればネットワーク効率は上がるが、メモリ消費量は増える。監視対象のメトリクス密度(`cardinality`)を考慮し、PrometheusのWrite Bufferとの整合性を取るのが腕の見せ所だ。
—
3. 「カーディナリティ爆発」を未然に防ぐハック
Prometheusの寿命を縮める最大の要因は、ラベルのカーディナリティ(一意な組み合わせの数)だ。特にKubernetesのPod名やユーザーIDをタグとして混ぜると、Prometheusは即死する。
OTel Collector側で `transform` プロセッサを使い、不要なラベルをドロップせよ。
processors:
transform:
metric_statements:
- context: datapoint
statements:
# 不要なラベルを削除し、Prometheusのメモリ消費を抑制する
- delete_key(attributes, “pod_uid”)
- delete_key(attributes, “container_id”)
この処理をPrometheus側で `relabel_configs` を書くのではなく、Collector側で前処理することで、ネットワーク帯域とPrometheusのCPU負荷を劇的に削減できる。
—
4. 移行戦略:段階的マイグレーションの設計
現行のPrometheus環境を捨てずにOTelへ移行するには、以下の「ハイブリッド・ブリッジ」戦略を取れ。
1. Phase 1: Collectorの導入
現行のPrometheusはそのままに、各ノードにOTel CollectorをDaemonSetとして配置し、`prometheusreceiver` で現行のメトリクスを吸い上げる。
2. Phase 2: データの多重送信
Collectorから「現行Prometheus」と「新メトリクス基盤(Prometheus/Thanos/Mimir)」へ二重送信を行う。
3. Phase 3: アプリケーションのOTLPネイティブ化
各言語のSDKをOTLP対応に変更し、`prometheusreceiver` を徐々に停止していく。
—
5. 伝説的アーキテクトからの提言
あなたが真のオブザーバビリティを追求するなら、「Prometheusはあくまで長期保存のためのデータベース(または短期のクエリエンジン)」と定義し直すべきだ。
メトリクスの収集、加工、ルーティングの責務はすべてOTel Collectorに移管せよ。これにより、将来的にPrometheusをThanosやMimir、あるいはGrafana Cloudへと切り替える際、アプリケーションコードを一切修正することなく、Collectorの設定変更だけで済む「疎結合な監視パイプライン」が完成する。
最後に:
ツールは使いこなすものではなく、システムの一部として制御するものだ。PrometheusのAPIをCLIから叩き、`rate()` や `histogram_quantile()` の結果を自動で解析して、異常検知の閾値を自動調整するスクリプトを書くレベルまで到達してほしい。
監視とは、ただの「記録」ではない。システムの「鼓動」を制御し、ボトルネックを可視化し、エンジニアを夜中のアラートから解放するための「防御機構」である。さあ、古い監視の形を捨て、次世代のパイプラインを構築せよ。