Prometheus ローカルストレージ

スポンサーリンク

Prometheusは監視結果を時系列データベースに格納します。時系列データベースはPrometheus同梱のローカルストレージを利用する事もサードパーティ製を利用する事もできます。このページではローカルストレージの操作方法を説明します。

前提

参照資料

動作確認済環境

  • Rocky Linux 8.6
  • Prometheus 2.36.2

ローカルストレージのパラメタ変更

パラメタ一覧

Prometheusはデフォルト設定で15日間保存される時系列データベースを同梱しています。この時系列データベースはPrometheusの起動引数を変更する事で挙動を変える事ができます。以下に起動引数の一覧をまとめます。

起動引数 意味
–storage.tsdb.path データベースディレクトリの指定
–storage.tsdb.retention.time データの保存期間。保存期間を超過したものは自動的に削除される。デフォルト設定は15日
–storage.tsdb.retention.size データの保存期間。storage.tsdb.retention.timeと異なり、B, KB, MB, GBなどのデータサイズで指定する。
–storage.tsdb.wal-compression WAL(write ahead log)を圧縮するか否か。データ量の削減に寄与するもののCPU使用率が増加する事に注意。

起動パラメタの指定方法

起動パラメタの指定方法は、Prometheusのインストール方法によって異なります。以下、RPM版をインストールした場合を例示します。

RPM版の場合は、systemdのお作法に基づいて起動引数が設定されています。/usr/lib/systemd/system/prometheus.serviceを確認すると、起動引数は環境変数PROMETHEUS_OPTSで指定できるようです。また、環境変数は/etc/default/prometheusに定義できる事が分かります。

[root@linux010 ~]# cat /usr/lib/systemd/system/prometheus.service 
# -*- mode: conf -*-

[Unit]
Description=The Prometheus monitoring system and time series database.
Documentation=https://prometheus.io
After=network.target

[Service]
EnvironmentFile=-/etc/default/prometheus
User=prometheus
ExecStart=/usr/bin/prometheus $PROMETHEUS_OPTS
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=5s
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

例えば/etc/default/prometheusを以下のように編集すると、保管期間を15日から21日に変更する事ができます。

# vi /etc/default/prometheus
PROMETHEUS_OPTS='--config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus/data \
  --storage.tsdb.retention.time=21d \
  --web.console.libraries=/usr/share/prometheus/console_libraries \
  --web.console.templates=/usr/share/prometheus/consoles'

prometheusを再起動させ設定を反映させます。

systemctl restart prometheus.service

psコマンドなどで設定が反映された事を確認します。

[root@linux010 ~]# ps aux | grep prometheus
root        1154  0.0  0.0 392428   400 ?        Ss   19:15   0:00 gpg-agent --homedir /var/cache/dnf/prometheus-1e74c44ceec9d40b/pubring --use-standard-socket --daemon
prometh+   11152  1.0  8.9 782908 67936 ?        Ssl  20:51   0:00 /usr/bin/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/var/lib/prometheus/data --storage.tsdb.retention.time=21d --web.console.libraries=/usr/share/prometheus/console_libraries --web.console.templates=/usr/share/prometheus/consoles
root       11164  0.0  0.1 221936  1204 pts/0    R+   20:51   0:00 grep --color=auto prometheus
[root@linux010 ~]#

ローカルストレージのデータ構造

データ構造概要

ローカルストレージのファイル・ディレクトリ構造を以下に示します。

[root@linux010 ~]# ls -l /var/lib/prometheus/data
合計 4
drwxr-xr-x 3 prometheus prometheus    68  7月 11 20:00 01G7PENM2R60R1TARA6GJ9J05Y
drwxr-xr-x 3 prometheus prometheus    68  7月 12 14:00 01G7RCF5AGMDMSY227BZVMXYDD
drwxr-xr-x 3 prometheus prometheus    68  7月 12 18:00 01G7RT6KQ3TK8CVFPZMZSB3QFR
drwxr-xr-x 3 prometheus prometheus    68  7月 12 20:00 01G7S12AYY61WHSNQ134ZTPPGT
drwxr-xr-x 3 prometheus prometheus    68  7月 12 20:00 01G7S12B10HA7A2A5KQVEJ0PY4
drwxr-xr-x 3 prometheus prometheus    68  7月 12 22:00 01G7S7Y26WCPHTKD88K65H19T6
drwxr-xr-x 3 prometheus prometheus    68  7月 13 00:00 01G7SESSF20EAKNWP64S9E9XTG
drwxr-xr-x 2 prometheus prometheus    34  7月 13 01:00 chunks_head
-rw-r--r-- 1 prometheus prometheus     0  7月 11 08:08 lock
-rw-r--r-- 1 prometheus prometheus 20001  7月 11 08:08 queries.active
drwxr-xr-x 3 prometheus prometheus    81  7月 13 00:00 wal
[root@linux010 ~]#

それぞれのファイル・ディレクトリの役割は以下の通りです。

ファイル名 意味
01G7PENM2R60R1TARA6GJ9J05Yなど 圧縮されたデータ
01G7RCF5AGMDMSY227BZVMXYDD 未圧縮の状態のデータ。2時間毎にディレクトリで分割され、「公式ドキュメント」ではこの分割単位をブロックと呼んでいる
chunks_head 現在書き込み中のデータ。もし、データベースが強制終了した場合は、WALを用いてクラッシュリカバリされる。
wal WAN(write ahead log)を格納するディレクトリ

非圧縮のブロック

各ブロックには、以下のようなmeta.jsonと呼ばれるファイルがあります。

[root@linux010 ~]# ls -l /var/lib/prometheus/data/01G7S7Y26WCPHTKD88K65H19T6/
合計 128
drwxr-xr-x 2 prometheus prometheus     20  7月 12 22:00 chunks
-rw-r--r-- 1 prometheus prometheus 121870  7月 12 22:00 index
-rw-r--r-- 1 prometheus prometheus    277  7月 12 22:00 meta.json
-rw-r--r-- 1 prometheus prometheus      9  7月 12 22:00 tombstones
[root@linux010 ~]# cat /var/lib/prometheus/data/01G7S7Y26WCPHTKD88K65H19T6/meta.json 
{
  "ulid": "01G7S7Y26WCPHTKD88K65H19T6",
  "minTime": 1657620008853,
  "maxTime": 1657627200000,
  "stats": {
    "numSamples": 120240,
    "numSeries": 1002,
    "numChunks": 1002
  },
  "compaction": {
    "level": 1,
    "sources": [
      "01G7S7Y26WCPHTKD88K65H19T6"
    ]
  },
  "version": 1
}
[root@linux010 ~]# 

minTimeとmaxTimeに着目すると、ブロックにどの期間のデータが保管されているかが分かります。このminTimeとmaxTimeはエポックミリ秒ですので、以下のような操作でJSTに変換する事もできます。

[root@linux010 ~]# date --date "@1657620008.853"
2022年  7月 12日 火曜日 19:00:08 JST
[root@linux010 ~]# date --date "@1657627200.000"
2022年  7月 12日 火曜日 21:00:00 JST
[root@linux010 ~]# 

圧縮済のブロック

圧縮済ブロックのmeta.jsonのcompactionに着目すると、複数のブロックが含まれている事が分かります。

[root@linux010 ~]# ls -l /var/lib/prometheus/data/01G7PENM2R60R1TARA6GJ9J05Y
合計 184
drwxr-xr-x 2 prometheus prometheus     20  7月 11 20:00 chunks
-rw-r--r-- 1 prometheus prometheus 178773  7月 11 20:00 index
-rw-r--r-- 1 prometheus prometheus    652  7月 11 20:00 meta.json
-rw-r--r-- 1 prometheus prometheus      9  7月 11 20:00 tombstones
[root@linux010 ~]# cat /var/lib/prometheus/data/01G7PENM2R60R1TARA6GJ9J05Y/meta.json 
{
  "ulid": "01G7PENM2R60R1TARA6GJ9J05Y",
  "minTime": 1657489028853,
  "maxTime": 1657519200000,
  "stats": {
    "numSamples": 529958,
    "numSeries": 1290,
    "numChunks": 5586
  },
  "compaction": {
    "level": 3,
    "sources": [
      "01G7NB0W207T90A1GHRPB4J6JD",
      "01G7NCAZQ3WBYKWDTXB3AN2C8W",
      "01G7NK6PYXZG0V1PTWN5393WFC",
      "01G7NT2E6W6F3XRNMBY9MH1EJW",
      "01G7P0Y5F1PZX2HX39H0FP5G5N"
    ],
    "parents": [
      {
        "ulid": "01G7NT2E8BSFRK19RR4ARGRFKJ",
        "minTime": 1657489028853,
        "maxTime": 1657497600000
      },
      {
        "ulid": "01G7PENM0ZA10FZCD2DRRHSJ1P",
        "minTime": 1657497608853,
        "maxTime": 1657519200000
      }
    ]
  },
  "version": 1
}
[root@linux010 ~]# 

Prometheusの時系列データベースは、「retention timeの10%」か「31日」の小さい方の間隔で圧縮されます。

データ削除

rmコマンドによる削除

状況によっては時系列データベースが肥大化し過ぎ、手作業による削除に迫られる事もあるかもしれません。まずは、商用運用に耐えられる操作ではありませんが、自宅環境などでお手軽に操作できるrmコマンドによる削除方法を紹介します。

全削除

もし、スクラップ&ビルドで環境を頻繁に作り直すような業務ならば、データの全削除をしたくなる事も多いでしょう。このような場合は、乱暴にデータディレクトリ全体をrm -rfして差し支えございません。以下に操作例を示します。

systemctl stop prometheus.service
rm -rf /var/lib/prometheus/data
systemctl start prometheus.service

ブロック単位の削除

ブロック単位での削除も可能です。若干乱暴な操作ですが、ブロックをrmコマンドで削除する事もできます。まずは、本当に削除されるかどうかを確認するために、削除前のグラフの描画を確認します。UTC時刻で21:37-06:00までの範囲が表示されている事を覚えていてください。

ブロック単位の削除 01

この状態で21:37-06:00のデータが含まれているブロックを削除します。操作例は以下のようになります。

[root@linux010 ~]# cat /var/lib/prometheus/data/01G7PENM2R60R1TARA6GJ9J05Y/meta.json 
{
  "ulid": "01G7PENM2R60R1TARA6GJ9J05Y",
  "minTime": 1657489028853,
  "maxTime": 1657519200000,
  "stats": {
    "numSamples": 529958,
    "numSeries": 1290,
    "numChunks": 5586
  },
  "compaction": {
    "level": 3,
    "sources": [
      "01G7NB0W207T90A1GHRPB4J6JD",
      "01G7NCAZQ3WBYKWDTXB3AN2C8W",
      "01G7NK6PYXZG0V1PTWN5393WFC",
      "01G7NT2E6W6F3XRNMBY9MH1EJW",
      "01G7P0Y5F1PZX2HX39H0FP5G5N"
    ],
    "parents": [
      {
        "ulid": "01G7NT2E8BSFRK19RR4ARGRFKJ",
        "minTime": 1657489028853,
        "maxTime": 1657497600000
      },
      {
        "ulid": "01G7PENM0ZA10FZCD2DRRHSJ1P",
        "minTime": 1657497608853,
        "maxTime": 1657519200000
      }
    ]
  },
  "version": 1
}[root@linux010 ~]# 
[root@linux010 ~]#
[root@linux010 ~]# date -u --date "@1657489028.853"
Sun Jul 10 21:37:08 UTC 2022
[root@linux010 ~]# date -u --date "@1657519200.000"
Mon Jul 11 06:00:00 UTC 2022
[root@linux010 ~]#
[root@linux010 ~]#
[root@linux010 ~]# rm -rf /var/lib/prometheus/data/01G7PENM2R60R1TARA6GJ9J05Y

操作後、21:37-06:00の範囲のデータが表示されなくなった事を確認できます。

ブロック単位の削除 02

REST APIによる削除

REST APIの有効化

前述のrmコマンドによるファイル削除はブロック単位の削除しかできません。ノード単位や時刻指定のデータ削除をする場合は、REST APIを使用します。

REST APIはadvanced user向けの機能でありデフォルトでは無効になっています。これを有効にするには起動引数–web.enable-admin-apiを与えます。起動引数の指定方法は、Prometheusのインストール方法に依存します。RPM版Prometheusを使用する場合は、/etc/default/prometheusを以下のように編集します。

# vi /etc/default/prometheus
PROMETHEUS_OPTS='--config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/var/lib/prometheus/data \
  --web.console.libraries=/usr/share/prometheus/console_libraries \
  --web.console.templates=/usr/share/prometheus/consoles \
  --web.enable-admin-api'

Delete Series

Prometheusの時系列データベースは、以下APIでデータをTombstones(墓石)に移動する事ができます。

POST /api/v1/admin/tsdb/delete_series
PUT /api/v1/admin/tsdb/delete_series

何もクエリ文字列を指定しない場合は全削除になりますが、以下のクエリ文字列を指定すれば部分的な削除が可能です。

クエリパラメタ 意味
match[] 削除対象をPromQLで指定する
start 削除開始時刻をrfc3339またはunix timestampで指定する
end 削除終了時刻をrfc3339またはunix timestampで指定する

それでは動作確認をしましょう。まずは、削除前のグラフを確認します。メトリックprocess_start_time_secondsは、prometheus, nodeの2つのジョブについてグラフ化されている事が分かります。

APIを用いた削除操作 01

この状況でjob=prometheusについて14:00-18:00のデータを削除してみましょう。操作例は以下のようになります。

URL='http://localhost:9090/api/v1/admin/tsdb/delete_series'
URL+='?match[]=process_start_time_seconds{job="prometheus"}'
URL+='&start=2022-07-12T14:00:00.0Z'
URL+='&end=2022-07-12T18:00:00.0Z'

curl -X POST -g ${URL}

グラフをブラウザで閲覧し、確かにjob=prometheusの14:00-18:00のみが削除されている事を確認します。

APIを用いた削除操作 02

Clean Tombstones

前述のAPI操作での削除はいわゆる論理削除でディスク上にデータは残っています。以下に示されるtombstonesがディスク上に残ったデータの実態です。

[root@linux010 ~]# ls -l /var/lib/prometheus/data/01G7TA8PJQY1VATAN2RB68Z398/
total 212
drwxr-xr-x 2 prometheus prometheus     20 Jul 13 08:00 chunks
-rw-r--r-- 1 prometheus prometheus 206350 Jul 13 08:00 index
-rw-r--r-- 1 prometheus prometheus    919 Jul 14 11:59 meta.json
-rw-r--r-- 1 prometheus prometheus     23 Jul 14 11:59 tombstones
[root@linux010 ~]#

tombstonesに残ったデータを完全に削除するには以下のAPIを実行します。

URL='http://localhost:9090/api/v1/admin/tsdb/clean_tombstones'
curl -X POST -g ${URL}
タイトルとURLをコピーしました