ストレージ

Prometheusはローカルオンディスク時系列データベースを含んでいますが、リモートストレージシステムとの統合もオプションで提供しています。

ローカルストレージ

Prometheusのローカル時系列データベースは、カスタムで非常に効率的な形式でローカルストレージにデータを格納します。

ディスク上のレイアウト

取り込まれたサンプルは、2時間ごとのブロックにグループ化されます。各2時間ブロックは、その時間枠のすべての時系列サンプルを含むchunksサブディレクトリ、メタデータファイル、およびインデックスファイル(chunksディレクトリ内の時系列にメトリック名とラベルをインデックス付けする)を含むディレクトリで構成されます。chunksディレクトリのサンプルは、デフォルトで最大512MBの1つ以上のセグメントファイルにグループ化されます。APIを介してシリーズが削除されると、削除レコードは個別の墓石ファイルに格納されます(データをチャンクセグメントからすぐに削除する代わりに)。

着信サンプルの現在のブロックはメモリに保持され、完全に永続化されません。Prometheusサーバーの再起動時に再生できるライトアヘッドログ(WAL)によって、クラッシュから保護されています。ライトアヘッドログファイルは、128MBのセグメントで`wal`ディレクトリに保存されます。これらのファイルには、まだ圧縮されていない生データが含まれています。そのため、通常のブロックファイルよりも大幅に大きくなります。Prometheusは、少なくとも3つのライトアヘッドログファイルを保持します。トラフィックの多いサーバーでは、少なくとも2時間分の生データを保持するために、3つ以上のWALファイルを保持することがあります。

Prometheusサーバーのデータディレクトリは、次のようになります。

./data
├── 01BKGV7JBM69T2G1BGBGM6KB12
│   └── meta.json
├── 01BKGTZQ1SYQJTR4PB43C8PD98
│   ├── chunks
│   │   └── 000001
│   ├── tombstones
│   ├── index
│   └── meta.json
├── 01BKGTZQ1HHWHV8FBJXW1Y3W0K
│   └── meta.json
├── 01BKGV7JC0RY8A6MACW02A2PJD
│   ├── chunks
│   │   └── 000001
│   ├── tombstones
│   ├── index
│   └── meta.json
├── chunks_head
│   └── 000001
└── wal
    ├── 000000002
    └── checkpoint.00000001
        └── 00000000

ローカルストレージの制限事項として、クラスタ化またはレプリケーションされていないことが挙げられます。そのため、ドライブまたはノードの停止に対して無制限にスケール可能または耐久性があるわけではなく、他の単一ノードデータベースと同様に管理する必要があります。

スナップショットはバックアップにお勧めです。スナップショットなしで行われたバックアップは、最後のWAL同期以降に記録されたデータが失われるリスクがあります(通常は2時間ごとに発生します)。適切なアーキテクチャを使用すれば、ローカルストレージに数年間のデータを保持できます。

または、リモート読み取り/書き込みAPIを介して外部ストレージを使用できます。これらのシステムは耐久性、パフォーマンス、効率が大きく異なるため、注意深く評価する必要があります。

ファイル形式の詳細については、TSDB形式を参照してください。

圧縮

最初の2時間ブロックは、最終的にバックグラウンドでより長いブロックに圧縮されます。

圧縮により、保持時間の最大10%、または31日間のいずれか短い期間にわたるデータを含む、より大きなブロックが作成されます。

運用上の側面

Prometheusには、ローカルストレージを設定するいくつかのフラグがあります。最も重要なのは次のとおりです。

  • --storage.tsdb.path:Prometheusがデータベースを書き込む場所。デフォルトはdata/です。
  • --storage.tsdb.retention.time:ストレージにサンプルを保持する時間。このフラグが設定されている場合、storage.tsdb.retentionを上書きします。このフラグとstorage.tsdb.retentionstorage.tsdb.retention.sizeのいずれも設定されていない場合、保持時間はデフォルトで15dになります。サポートされている単位:y、w、d、h、m、s、ms。
  • --storage.tsdb.retention.size:保持するストレージブロックの最大バイト数。最も古いデータが最初に削除されます。デフォルトは0または無効です。サポートされている単位:B、KB、MB、GB、TB、PB、EB。例:「512MB」。2の累乗に基づいているため、1KBは1024Bです。永続ブロックのみが削除されてこの保持が尊重されますが、WALとmマッピングされたチャンクは合計サイズにカウントされます。したがって、ディスクの最小要件は、`wal`(WALとチェックポイント)と`chunks_head`(mマッピングされたヘッドチャンク)ディレクトリの組み合わせによって占められるピークスペースです(2時間ごとにピークに達します)。
  • --storage.tsdb.retentionstorage.tsdb.retention.timeに置き換えられました。
  • --storage.tsdb.wal-compression:ライトアヘッドログ(WAL)の圧縮を有効にします。データによっては、WALのサイズを半分に削減し、CPU負荷をわずかに増やすことができます。このフラグは2.11.0で導入され、2.20.0でデフォルトで有効になりました。有効にすると、2.11.0より前のバージョンにPrometheusをダウングレードするには、WALを削除する必要があります。

Prometheusは、サンプルあたり平均わずか1〜2バイトを格納します。したがって、Prometheusサーバーの容量を計画するには、次の概算式を使用できます。

needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample

取り込まれるサンプルのレートを下げるには、スクレイプする時系列の数(ターゲットの削減またはターゲットあたりのシリーズの削減)、またはスクレイプ間隔の増加のいずれかを行うことができます。ただし、シリーズ内のサンプルの圧縮のために、シリーズの数の削減の方が効果的です。

何らかの理由でローカルストレージが破損した場合、問題に対処するための最善の方法は、Prometheusをシャットダウンしてからストレージディレクトリ全体を削除することです。個々のブロックディレクトリ、またはWALディレクトリを削除して問題を解決することもできます。これは、ブロックディレクトリごとに約2時間分のデータが失われることを意味します。繰り返しますが、Prometheusのローカルストレージは、長期的な耐久性のあるストレージを目的としていません。外部ソリューションは、拡張された保持とデータ耐久性を提供します。

注意:POSIX準拠ではないファイルシステムは、回復不能な破損が発生する可能性があるため、Prometheusのローカルストレージではサポートされていません。NFSファイルシステム(AWSのEFSを含む)はサポートされていません。NFSはPOSIX準拠である可能性がありますが、ほとんどの実装は準拠していません。信頼性のためにローカルファイルシステムを使用することを強くお勧めします。

時間とサイズの両方の保持ポリシーが指定されている場合、最初にトリガーされた方が使用されます。

期限切れのブロックのクリーンアップはバックグラウンドで行われます。期限切れのブロックを削除するまでに最大2時間かかる場合があります。ブロックは完全に期限切れになるまで削除されません。

適切な保持サイズの決定

storage.tsdb.retention.sizeを使用してサイズ制限を設定している場合、Prometheusに割り当てたストレージに対してこの値の適切なサイズを考慮する必要があります。保持サイズを減らしてバッファーを提供することで、割り当てられたPrometheusのストレージがいっぱいになる前に古いエントリが削除されるようにすることをお勧めします。

現時点では、保持サイズを割り当てられたPrometheusのディスクスペースの最大80〜85%に設定することをお勧めします。これにより、ディスクの制限に達する前に古いエントリが削除される可能性が高まります。

リモートストレージ統合

Prometheusのローカルストレージは、単一ノードのスケーラビリティと耐久性に限定されています。Prometheus自体でクラスタ化されたストレージを解決しようとする代わりに、Prometheusはリモートストレージシステムとの統合を可能にするインターフェースのセットを提供しています。

概要

Prometheusは、3つの方法でリモートストレージシステムと統合されます。

  • Prometheusは、取り込んだサンプルを標準化された形式でリモートURLに書き込むことができます。
  • Prometheusは、他のPrometheusサーバーから標準化された形式でサンプルを受信できます。
  • Prometheusは、標準化された形式でリモートURLからサンプルデータを読み取ることができます。

Remote read and write architecture

読み取りと書き込みのプロトコルの両方が、HTTP経由でsnappy圧縮プロトコルバッファーエンコーディングを使用します。これらのプロトコルはまだ安定したAPIとは見なされておらず、将来、Prometheusとリモートストレージ間のすべてのホップでHTTP/2を安全にサポートできると想定できるようになった場合、HTTP/2経由のgRPCを使用するように変更される可能性があります。

Prometheusでのリモートストレージ統合の設定の詳細については、Prometheus設定ドキュメントのリモート書き込みセクションとリモート読み取りセクションを参照してください。

組み込みのリモート書き込みレシーバは、`--web.enable-remote-write-receiver`コマンドラインフラグを設定することで有効化できます。有効化すると、リモート書き込みレシーバのエンドポイントは`/api/v1/write`になります。

リクエストおよびレスポンスメッセージの詳細については、リモートストレージプロトコルバッファ定義を参照してください。

読み取りパスにおいて、Prometheusはリモートエンドからラベルセレクタと時間範囲のセットに対する生の時系列データのみを取得することに注意してください。生のデータに対するPromQL評価はすべてPrometheus自身で行われます。これは、必要なデータすべてを最初にクエリを実行するPrometheusサーバーにロードし、そこで処理する必要があるため、リモート読み取りクエリにはスケーラビリティの限界があることを意味します。しかし、PromQLの完全に分散された評価をサポートすることは、現時点では実現不可能と判断されました。

既存の統合

リモートストレージシステムとの既存の統合の詳細については、統合ドキュメントを参照してください。

OpenMetrics形式からのバックフィル

概要

ユーザーがOpenMetrics形式のデータからTSDBにブロックを作成したい場合、バックフィルを使用して行うことができます。ただし、直近3時間(現在のヘッドブロック)のデータのバックフィルは安全ではないことに注意する必要があります。この時間範囲は、Prometheusが現在変更中のヘッドブロックと重複する可能性があるためです。バックフィルは新しいTSDBブロックを作成し、それぞれに2時間分のメトリクスデータが含まれます。これにより、ブロック作成時のメモリ要件が制限されます。2時間ブロックのより大きなブロックへの圧縮は、後でPrometheusサーバー自体によって行われます。

一般的なユースケースとしては、別の監視システムまたは時系列データベースからPrometheusにメトリクスデータを移行することが挙げられます。そのためには、ユーザーはまずソースデータをOpenMetrics形式に変換する必要があります。これは、以下に説明するバックフィルの入力形式です。

ネイティブヒストグラムと陳腐化マーカーはこの手順ではサポートされていません。これらはOpenMetrics形式では表現できないためです。

使用方法

バックフィルはPromtoolコマンドラインを使用して実行できます。Promtoolはブロックを出力ディレクトリに書き込みます。デフォルトの出力ディレクトリは`./data/`ですが、サブコマンドのオプション引数として目的の出力ディレクトリ名を指定することで変更できます。

promtool tsdb create-blocks-from openmetrics <input file> [<output directory>]

ブロックの作成後、Prometheusのデータディレクトリに移動します。Prometheusの既存のブロックと重複する場合は、Prometheusバージョンv2.38以前では`--storage.tsdb.allow-overlapping-blocks`フラグを設定する必要があります。バックフィルされたデータは、Prometheusサーバーで設定された保持ポリシー(時間またはサイズによる)に従うことに注意してください。

より長いブロック期間

デフォルトでは、promtoolはブロックにデフォルトのブロック期間(2時間)を使用します。これは一般的に最も適切な方法です。しかし、長い時間範囲にわたってデータをバックフィルする場合は、ブロック期間の値を大きくすることで、バックフィルの速度を向上させ、後のTSDBによる追加の圧縮を回避できます。

`--max-block-duration`フラグを使用すると、ユーザーはブロックの最大期間を設定できます。バックフィルツールは、この値以下の適切なブロック期間を選択します。

大きなブロックは、大規模なデータセットのバックフィルのパフォーマンスを向上させる可能性がありますが、欠点もあります。時間ベースの保持ポリシーでは、(潜在的に大きな)ブロックのサンプルが1つでも保持ポリシーの範囲内にある場合、そのブロック全体を保持する必要があります。一方、サイズベースの保持ポリシーでは、TSDBがわずかにサイズ制限を超えた場合でも、ブロック全体が削除されます。

したがって、ブロック数を少なくし、大きなブロック期間を選択するバックフィルは、注意深く行う必要があり、本番環境では推奨されません。

レコーディングルールのためのバックフィル

概要

新しいレコーディングルールが作成されると、そのルールに関する履歴データはありません。レコーディングルールのデータは、作成時刻以降にのみ存在します。`promtool`を使用すると、履歴レコーディングルールデータを作成できます。

使用方法

すべてのオプションを表示するには、`$ promtool tsdb create-blocks-from rules --help`と実行します。

使用例

$ promtool tsdb create-blocks-from rules \
    --start 1617079873 \
    --end 1617097873 \
    --url http://mypromserver.com:9090 \
    rules.yaml rules2.yaml

提供されたレコーディングルールファイルは、通常のPrometheusルールファイルである必要があります。

`promtool tsdb create-blocks-from rules`コマンドの出力は、レコーディングルールファイル内のすべてのルールに関する履歴ルールデータを含むブロックを含むディレクトリです。デフォルトの出力ディレクトリは`data/`です。この新しいブロックデータを使用するには、ブロックを実行中のPrometheusインスタンスのデータディレクトリ`storage.tsdb.path`に移動する必要があります(Prometheusバージョンv2.38以前の場合は、`--storage.tsdb.allow-overlapping-blocks`フラグを有効にする必要があります)。移動後、新しいブロックは次の圧縮実行時に既存のブロックとマージされます。

制限事項

  • 重複する開始/終了時刻でルールバックフィラーを複数回実行すると、ルールバックフィラーが実行されるたびに同じデータを含むブロックが作成されます。
  • レコーディングルールファイル内のすべてのルールが評価されます。
  • レコーディングルールファイルで`interval`が設定されている場合、ルールバックフィルコマンドの`eval-interval`フラグよりも優先されます。
  • アラートは、レコーディングルールファイルに含まれていても、現在無視されます。
  • 同じグループ内のルールは、先行するルールの結果を参照できません。つまり、バックフィルされている他のルールを参照するルールはサポートされていません。回避策としては、複数回バックフィルを実行し、依存関係のあるデータを最初に作成し(そしてPrometheusサーバーのデータディレクトリに移動してPrometheus APIからアクセスできるようにする)、です。

このドキュメントはオープンソースです。問題点やプルリクエストを送信することで、改善にご協力ください。