Prometheusアーキテクチャ詳解

Part 1 - Prometheusとは で学んだ基本概念をもとに、ここではPrometheus各コンポーネントの詳細な仕組みと、それらがどのように連携してメトリクス監視を実現しているかを理解します。スクレイパーの動作メカニズム、メタラベルの役割、データフロー、そしてストレージの仕組みを実装レベルで把握することで、設定・運用時の判断がより的確になります。

Prometheus Server の内部構造

Prometheus Server は、単なるデータ保存システムではなく、複数の重要な機能を持つシステムです。ここでは、その詳細な動作メカニズムを見ていきます。

スクレイパーの動作メカニズム

Prometheus Server に内蔵されたスクレイパーは、定期的に各種ターゲット(サーバー、アプリケーション等)の /metrics エンドポイントにHTTPリクエストを送信し、メトリクスデータを取得します。この処理は、prometheus.yml の設定に基づいて実行されます。

スクレイプサイクルは以下の流れで進みます。

  1. ターゲット候補の準備:静的設定またはサービスディスカバリーから、スクレイプ対象のターゲットを一覧化します。
  2. メタラベルの生成:各ターゲットに対して、__meta_* というメタラベルを付与します。これらは一時的なラベルで、後述するリラベル処理の基礎となります。
  3. リラベル処理:メタラベルと既存のラベルを操作し、最終的なターゲットのラベルを決定します。
  4. HTTP リクエスト:決定したターゲットアドレスに対して、設定されたスクレイプ間隔(デフォルト1分)で /metrics エンドポイントからメトリクスデータを取得します。
  5. メトリクスのリラベル:取得したメトリクスに対して、metric_relabel_configs に基づくリラベル処理を実施し、不要なメトリクスの除外やラベルの修正を行います。
  6. TSDB への保存:処理されたメトリクスを時系列データベースに保存します。

このプロセスは、スクレイプ間隔ごとに全ターゲットについて並行実行されます。

メトリクスのテキスト形式と解析

Prometheus が取得するメトリクスは、OpenMetrics 形式(またはPrometheusテキスト形式)というテキストベースのフォーマットです。以下は実際の例です。

# HELP node_cpu_seconds_total Seconds the CPUs spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="0",mode="idle"} 86400.12
node_cpu_seconds_total{cpu="0",mode="system"} 1234.56
node_cpu_seconds_total{cpu="1",mode="idle"} 86392.78
node_cpu_seconds_total{cpu="1",mode="system"} 1242.34

# HELP node_memory_MemFree_bytes Memory information field MemFree_bytes.
# TYPE node_memory_MemFree_bytes gauge
node_memory_MemFree_bytes 1024000000

Prometheus は /metrics エンドポイントから取得したテキストを解析し、メトリクス名、ラベル、値(とタイムスタンプ)を抽出します。このプロセスは高速に行われる必要があるため、効率的なパーサが実装されています。

タイムシリーズデータベース(TSDB)の概要

Prometheus の TSDB は、時系列データの効率的な保存と検索に特化した実装です。データはメモリ上のインデックスと、ディスク上のブロック構造で管理されます。

TSDB の基本構造:

  • インデックス:メトリクス名、ラベル値の組み合わせからデータブロック上の位置を高速に検索するためのインデックス
  • ブロック:数時間分のメトリクスデータをひとまとめにしたファイル。デフォルトでは2時間ごとに新しいブロックが作成されます
  • ウォルファイル(WAL):未確定のデータを一時的に記録。サーバーがクラッシュした場合のデータ損失を防ぎます
  • チャンク:ブロック内のメトリクスごとのデータ領域。圧縮されて保存されます

このため、Prometheus は大量のメトリクスを効率的に保存し、PromQL によるクエリを高速に実行できるわけです。

Exporter との連携メカニズム

Prometheus が実際にメトリクスを取得する相手が Exporter です。ここでは、その詳細な連携方式を見ていきます。

Exporter の役割と実装形態

Exporter は、システムやアプリケーションのメトリクスをPrometheusが読み取れる形式で公開するコンポーネントです。実装形態は複数あります。

スタンドアロン型 Exporter:別プロセスとして動作するExporter。例えば Node Exporter は単独のバイナリで起動し、ポート9100でメトリクスを公開します。Prometheus は定期的にこのポートの /metrics エンドポイントにアクセスして、OSレベルのメトリクス(CPU、メモリ、ディスク等)を取得します。

ライブラリ型 Exporter:アプリケーションに組み込まれたPrometheusクライアントライブラリ。アプリケーション側で /metrics エンドポイントを実装し、そこでアプリケーション固有のメトリクスを公開します。

サービスディスカバリーとメタラベル

Prometheus の真の強力さを引き出すのが、サービスディスカバリー(SD)とメタラベルの仕組みです。特に Kubernetes やクラウド環境では、サーバーやコンテナが動的に立ち上がり消滅するため、固定的な設定だけでは対応できません。

サービスディスカバリーを使うと、外部のシステム(Kubernetes API、Consul、AWS API等)から、スクレイプ対象のターゲット一覧を動的に取得できます。例えば Kubernetes なら、Prometheus は定期的に Kubernetes API に問い合わせて、稼働中のポッドの一覧を取得します。

取得したターゲット情報には、メタラベルという一時的なラベルが自動的に付与されます。Kubernetes の場合、以下のようなメタラベルが生成されます。

__meta_kubernetes_pod_name
__meta_kubernetes_pod_namespace
__meta_kubernetes_pod_label_app
__meta_kubernetes_pod_annotation_prometheus_io_scrape

これらのメタラベルは、relabel_configs による後続の処理で活用されます。

リラベル処理によるターゲット・メトリクスの操作

メタラベルを含む各ラベルを、relabel_configs で操作することで、柔軟なターゲット管理が可能です。以下はよくあるパターンです。

例:Kubernetes ポッド監視の場合

yaml
scrape_configs:
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      # prometheus.io/scrape: "true" アノテーションのあるポッドのみを対象
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: "true"
      
      # スクレイプポートをメタラベルから抽出
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        target_label: __param_port
        regex: ([^:]+)(?::\d+)?;(\d+)
      
      # ジョブラベルをポッドの属するアプリケーション名から生成
      - source_labels: [__meta_kubernetes_pod_label_app]
        action: replace
        target_label: job
      
      # インスタンスラベルをポッド名とnamespaceで生成
      - source_labels: [__meta_kubernetes_pod_name, __meta_kubernetes_pod_namespace]
        action: replace
        target_label: instance
        separator: ":"

relabel_configs エントリは以下の要素から構成されます。

要素説明
source_labels操作対象のラベル(複数指定可)
regexマッチングするパターン
actionkeep(マッチしたものだけ保持)、drop(マッチしたものを除外)、replace(ラベル値を置換)等
target_label置換後のターゲットラベル名
separator複数ラベルを連結する際の区切り文字

このリラベル処理は、スクレイプ前に実施される「ターゲット レベル」の処理です。一方、metric_relabel_configs は、メトリクスを TSDB に保存する直前に実施される「メトリクス レベル」の処理で、不要なメトリクスをフィルタリングしたり、メトリクス名やラベルを修正したりします。

データフロー完全図とスクレイプ~保存までの流れ

ここまでの説明を図解化して、エンドツーエンドのデータフローを理解しましょう。

フローの詳細:

  1. サービスディスカバリー:Prometheus が Kubernetes API、Consul、ファイルシステム等からターゲット候補を取得
  2. メタラベル生成:取得したターゲットに __meta_* メタラベルを付与
  3. ターゲット リラベルrelabel_configs でメタラベルと既存ラベルを操作し、最終的なターゲットを決定
  4. スクレイプ:HTTP GET で /metrics エンドポイントからメトリクスを取得
  5. テキスト解析:取得したテキストをパースしてメトリクス名、ラベル、値を抽出
  6. メトリクス リラベルmetric_relabel_configs でメトリクスをフィルタリング・修正
  7. TSDB 保存:処理済みメトリクスを時系列データベースに保存

この流れは、スクレイプ間隔ごとにすべてのターゲットについて並行実行されます。

ストレージ・リテンション戦略

Prometheus のストレージは、デフォルトではローカルディスクに保存されます。ここでその仕組みと設定方法を見ていきます。

ローカルストレージ(TSDB)の構造

TSDB のディレクトリ構造は以下のようになります。

prometheus-data/
  ├── wal/                  # Write-Ahead Log
  │   ├── 00000001
  │   └── 00000002
  ├── 2026-05-02T00-00/    # ブロック(2時間単位)
  │   ├── chunks
  │   │   └── 000001
  │   ├── index
  │   ├── meta.json
  │   └── tombstones
  ├── 2026-05-02T02-00/
  └── index/                # インデックスメタデータ

各ブロックは原子性で作成されるため、Prometheus がクラッシュしても既存ブロックが破損することはありません。

リテンション設定

データの保持期間は、時間ベースまたは容量ベースで制御できます。これは Prometheus 起動時のフラグで設定します。

bash
# 時間ベース:30日間保持
prometheus \
  --storage.tsdb.retention.time=30d

# 容量ベース:50GBまで保持
prometheus \
  --storage.tsdb.retention.size=50GB

# 両方指定の場合、先に達した方が優先
prometheus \
  --storage.tsdb.retention.time=30d \
  --storage.tsdb.retention.size=50GB

ディスク容量の見積もりは、以下の目安で計算します。

月間ディスク使用量 ≈ メトリクス数 × 1時間当たりのサンプル数 × 保持日数 × 1.5 / (24 * 365)

例えば、10,000個のメトリクス、1秒ごとのスクレイプ(3,600サンプル/時間)、30日保持の場合:

月間容量 ≈ 10,000 × 3,600 × 30 × 1.5 / (24 × 365) ≈ 18.5GB

リモートストレージの概念

Prometheus のローカルストレージは、単一サーバー内での保存に最適です。ただし、大規模な環境では以下の課題が生じます。

  • スケーラビリティ:単一サーバーのディスク容量には限界がある
  • 長期保存:数年単位の歴史データを保持したい場合、ローカルストレージは非効率
  • 高可用性:複数の Prometheus インスタンス間でのデータ共有が困難

こうした課題を解決するのが、リモートストレージです。Prometheus は、取得したメトリクスを外部ストレージシステム(Thanos、InfluxDB、TimescaleDB等)に送信することで、スケーラブルで長期保存可能な構成を実現できます。

リモートストレージへの書き込みは、prometheus.yml で以下のように設定します。

yaml
remote_write:
  - url: http://thanos-receiver:19291/api/v1/receive
    queue_config:
      capacity: 10000
      max_shards: 200
      max_samples_per_send: 500

リモートストレージを使用した場合の利点:

利点説明
スケーラビリティメトリクス数の増加に応じて、ストレージシステムを水平スケール可能
長期保存数年単位の歴史データを効率的に保存・検索可能
高可用性複数の Prometheus インスタンスからリモートストレージに書き込み、単一の真実の源を実現
グローバル集計Thanos 等のツールを使用して、複数リージョンのメトリクスを統一的に管理

次のパートで詳しく解説しますが、本番環境では多くの場合、ローカルストレージとリモートストレージを組み合わせた構成を採用します。

まとめに向けて

Prometheus のアーキテクチャを実装レベルで理解することで、以下のことが可能になります。

  • スクレイプの失敗原因を特定し、対応するための診断スキル
  • メタラベルとリラベル処理を活用した、柔軟で保守性の高い監視設定の構築
  • リソース要件の見積もりと、ストレージ戦略の最適化

次のパート「Part 1-2. インストール・セットアップ」では、こうした知識をもとに、実際に Prometheus を導入するための具体的な手順を解説します。


前のパート: Part 1 - Prometheusとは
次のパート: Part 1-2. インストール・セットアップ