これは、なにをしたくて書いたもの?
Prometheusのストレージまわりがちょっと気になって、いくつか見ていくことにしました。
最初に、Snapshotについて見ていきたいと思います。
Snapshot?
TSDB Admin APIに、Snapshotを取得できるAPIが登場します。
TSDBというのは、Prometheusの時系列データベースのことです。
GitHub - prometheus/tsdb: The Prometheus time series database layer.
Prometheus 2.9.2では、TSDB 0.7.1を使用しています。
https://github.com/prometheus/prometheus/blob/v2.9.2/go.mod#L82
そのフォーマットについては、こちらに記載があります。
tsdb/README.md at v0.7.1 · prometheus/tsdb · GitHub
で、SnapshotというのはTSDB Admin APIを使って取得できる、TSDBのその時点のデータをデータディレクトリの配下に
スナップショットとして作成する機能です。
こちらを使って、Snapshotの取得して、リストアまで行ってみたいと思います。
環境
今回の環境は、こちらです。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.2 LTS Release: 18.04 Codename: bionic
Prometheusのバージョンは、2.9.2を利用します。
とりあえず、起動してみる
まずは、Prometheusをデフォルト設定で起動してみます。
$ ./prometheus level=info ts=2019-04-28T17:19:55.195Z caller=main.go:285 msg="no time or size retention was set so using the default time retention" duration=15d level=info ts=2019-04-28T17:19:55.195Z caller=main.go:321 msg="Starting Prometheus" version="(version=2.9.2, branch=HEAD, revision=d3245f15022551c6fc8281766ea62db4d71e2747)" level=info ts=2019-04-28T17:19:55.195Z caller=main.go:322 build_context="(go=go1.12.4, user=root@1d43b6951e8f, date=20190424-15:32:31)" level=info ts=2019-04-28T17:19:55.195Z caller=main.go:323 host_details="(Linux 4.15.0-48-generic #51-Ubuntu SMP Wed Apr 3 08:28:49 UTC 2019 x86_64 7020bd11d63d (none))" level=info ts=2019-04-28T17:19:55.195Z caller=main.go:324 fd_limits="(soft=1048576, hard=1048576)" level=info ts=2019-04-28T17:19:55.195Z caller=main.go:325 vm_limits="(soft=unlimited, hard=unlimited)" level=info ts=2019-04-28T17:19:55.196Z caller=web.go:416 component=web msg="Start listening for connections" address=0.0.0.0:9090 level=info ts=2019-04-28T17:19:55.196Z caller=main.go:640 msg="Starting TSDB ..." level=info ts=2019-04-28T17:19:55.202Z caller=main.go:655 msg="TSDB started" level=info ts=2019-04-28T17:19:55.202Z caller=main.go:724 msg="Loading configuration file" filename=prometheus.yml level=info ts=2019-04-28T17:19:55.203Z caller=main.go:751 msg="Completed loading of configuration file" filename=prometheus.yml level=info ts=2019-04-28T17:19:55.203Z caller=main.go:609 msg="Server is ready to receive web requests."
この状態でも、Prometheusのデフォルト設定で、Prometheus自身のメトリクスを取得するようになっています。
# A scrape configuration containing exactly one endpoint to scrape: # Here it's Prometheus itself. scrape_configs: # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. - job_name: 'prometheus' # metrics_path defaults to '/metrics' # scheme defaults to 'http'. static_configs: - targets: ['localhost:9090']
とりあえず、「process_cpu_seconds_total」でも見てみましょう。
取得されたメトリクスが表示されています。
ここで、データディレクトリの中を見てみます。
$ find data -type f data/wal/00000000 data/lock
現状はこうです、と。では、ドキュメントに習ってSnapshotを取ってみます。
すると、怒られます。
$ curl -XPOST http://localhost:9090/api/v1/admin/tsdb/snapshot {"status":"error","errorType":"unavailable","error":"admin APIs disabled"}
ドキュメントを見返すと、起動時に「--web.enable-admin-api」オプションが必要なようです。
仕方がないので、1度Prometheusを停止して、「--web.enable-admin-api」オプションを付与して起動しなおします。
$ ./prometheus --web.enable-admin-api
再起動したので、メトリクスを取得できていないタイミングができてしまいましたが…。
気を取り直して、Snapshot取得に再チャレンジ。
※ちなみに、Prometheus 2.9からPUTでの呼び出しも可能だそうです
$ curl -XPOST http://localhost:9090/api/v1/admin/tsdb/snapshot level=info ts=2019-04-28T17:36:41.486Z caller=compact.go:499 component=tsdb msg="write block" mint=1556472013810 maxt=1556472988810 ulid=01D9JGADE0D7D2W9A5FT93YT0N duration=77.938466ms {"status":"success","data":{"name":"20190428T173641Z-5954bed5ce03a992"}}
今度はうまくいきました。
Snapshotを含めたデータディレクトリの内容は、こんな感じになっています。
$ find data -type f data/wal/00000000 data/lock data/snapshots/20190428T173641Z-5954bed5ce03a992/01D9JGADE0D7D2W9A5FT93YT0N/meta.json data/snapshots/20190428T173641Z-5954bed5ce03a992/01D9JGADE0D7D2W9A5FT93YT0N/index data/snapshots/20190428T173641Z-5954bed5ce03a992/01D9JGADE0D7D2W9A5FT93YT0N/tombstones data/snapshots/20190428T173641Z-5954bed5ce03a992/01D9JGADE0D7D2W9A5FT93YT0N/chunks/000001
Snapshotの「name」は、「snapshots」直下のディレクトリ名(今回は「20190428T173641Z-5954bed5ce03a992」)に
なるようですね。
Snapshot内のmeta.json以外のファイルは全部バイナリですが、中身を見てみるとこんな感じでした。
data/snapshots/20190428T173641Z-5954bed5ce03a992/01D9JGADE0D7D2W9A5FT93YT0N/meta.json
{ "ulid": "01D9JGADE0D7D2W9A5FT93YT0N", "minTime": 1556472013810, "maxTime": 1556472988810, "stats": { "numSamples": 29418, "numSeries": 485, "numChunks": 485 }, "compaction": { "level": 1, "sources": [ "01D9JGADE0D7D2W9A5FT93YT0N" ] }, "version": 1 }
ここで、1度、Prometheusを停止してデータディレクトリをリネームしてみます。
$ mv data data-current
$ ./prometheus --web.enable-admin-api
Web UIを見てみると、当然のことながらデータがなくなっています。
ここでもう1度Prometheusを停止させてデータディレクトリを削除し、空のデータディレクトリを作成します。
$ rm -r data $ mkdir data
この中に、先ほど取得したSnapshotの「中身」をコピーします。
$ cp -R data-current/snapshots/20190428T173641Z-5954bed5ce03a992/* data
つまり、こういう状態になります。
$ find data -type f data/01D9JGADE0D7D2W9A5FT93YT0N/meta.json data/01D9JGADE0D7D2W9A5FT93YT0N/index data/01D9JGADE0D7D2W9A5FT93YT0N/tombstones data/01D9JGADE0D7D2W9A5FT93YT0N/chunks/000001
これでPrometheusを起動させて、Web UIを確認してみます。
$ ./prometheus --web.enable-admin-api
すると、今度はSnapshotで取得したデータが見えるようになっています。
もちろん、止めていた間はデータがないことになってしまいます。
これで、1度起動できたからといって、Snapshotからコピーしたデータを削除すると
$ rm -rf data/01D9JGADE0D7D2W9A5FT
Snapshotを取得した時のデータがなくなります。
Snapshotから戻したデータも、そのまま置いておきましょう、と。
Snapshotは複数回取得することができますが、
$ curl -XPOST http://localhost:9090/api/v1/admin/tsdb/snapshot level=info ts=2019-04-28T17:50:07.527Z caller=compact.go:499 component=tsdb msg="write block" mint=1556472013810 maxt=1556473093810 ulid=01D9JH30JNEYZRKPPFA056R4BA duration=81.852128ms {"status":"success","data":{"name":"20190428T175007Z-5a80b8f4cc055ea8"}
持っているデータ全体のSnapshotなので、どの時点のものを利用するかを選びましょう。
$ find data -type f data/wal/00000000 data/lock data/snapshots/20190428T173641Z-5954bed5ce03a992/01D9JGADE0D7D2W9A5FT93YT0N/meta.json data/snapshots/20190428T173641Z-5954bed5ce03a992/01D9JGADE0D7D2W9A5FT93YT0N/index data/snapshots/20190428T173641Z-5954bed5ce03a992/01D9JGADE0D7D2W9A5FT93YT0N/tombstones data/snapshots/20190428T173641Z-5954bed5ce03a992/01D9JGADE0D7D2W9A5FT93YT0N/chunks/000001 data/snapshots/20190428T175007Z-5a80b8f4cc055ea8/01D9JH30JNEYZRKPPFA056R4BA/meta.json data/snapshots/20190428T175007Z-5a80b8f4cc055ea8/01D9JH30JNEYZRKPPFA056R4BA/index data/snapshots/20190428T175007Z-5a80b8f4cc055ea8/01D9JH30JNEYZRKPPFA056R4BA/tombstones data/snapshots/20190428T175007Z-5a80b8f4cc055ea8/01D9JH30JNEYZRKPPFA056R4BA/chunks/000001
これで、最低限の確認はできた気がします。
ドキュメントにはSnapshotのことは書いているものの、リストアのことについてはほぼ触れられていなかったので、
どう戻したらいいのかちょっと困りました。
他にも、範囲を絞ったり、ヘッドブロックにのみ存在してまだディスクに圧縮されていないSnapshotのデータをスキップ
するようにもできるみたいですが、今回はパスです。
Prometheusのストレージについては、他にもリテンション(データの保持期間)や
外部ストレージのことなども考えないといけないようですが、
これらは順次やっていくとしましょう。
今回は、こんなところで。