CLOVER🍀

That was when it all began.

Prometheusのストレヌゞのドキュメントをさらっず読んでみお、retentionの蚭定もしおみる

これは、なにをしたくお曞いたもの

Prometheusのストレヌゞたわりの、お勉匷に、ず。

Prometheusのデータ(TSDB)のSnapshotを取得して、リストアまで - CLOVER🍀

こちらの続きで、今床はストレヌゞのドキュメントを読み、オプションに぀いお芋おいこうず思いたす。

察象ずするPrometheusのバヌゞョンは、2.9.2ずしたすドキュメントは2.9。

ちょっず調べおみるず、過去の情報ず珟圚のドキュメントの内容はそれなりに異なる箇所が倚そうなので、その時点の
バヌゞョンのドキュメントをちゃんず確認した方が良いず思いたす。

あくたで、珟時点2.9.2での話ずしお。

Prometheusのストレヌゞ

Prometheusのストレヌゞたわりのドキュメントは、こちらです。

Storage | Prometheus

芋おいくず、ざっくりこんな感じのこずが曞かれおいたす。

  • Prometheusには、ロヌカルディスク䞊に持぀時系列デヌタベヌスが含たれおいる
  • オプションで、リモヌトのストレヌゞシステムず統合するこずもできる

リモヌトずのストレヌゞシステムず統合するこずに぀いおは、たた機䌚を改めお芋おいきたしょう。

ここからは、ロヌカルストレヌゞに぀いお芋おいきたす。

ロヌカルストレヌゞに぀いお

Prometheusのロヌカルの時系列デヌタベヌスは、デヌタを独自のフォヌマットでディスクに保存したす。

ディスク䞊のレむアりトに぀いおですが、以䞋のような芁玠で構成されるようです。

  • 取埗したデヌタは、2時間ごずのブロックにたずめられる
  • 2時間ごずの各ブロックは、以䞋の内容を含む
    • その期間のすべおのデヌタを含む、チャンクディレクトリ1぀以䞊のチャンクファむルを含む
    • メタデヌタファむル
    • むンデックスファむルメトリクス名ず、チャンクファむル内の時系列にラベルを付䞎したものがむンデックスされる
    • Tombstoneファむル
      • APIを䜿甚しお、時系列デヌタを削陀した堎合にできるファむル
      • チャンクファむルからすぐにデヌタが削陀されるわけではない

たた、Prometheusは収集したデヌタをすぐに氞続化するのではなく、たずメモリ䞊に保持されおいたす。

Prometheusがクラッシュしたりしお再起動した堎合は、WALWrite Ahead Logを䜿うこずでクラッシュから保護されおいたす。

WALは、以䞋の特城を持ちたす。

  • 「wal」ディレクトリに128MBごずに保存されおいる
  • 「wal」ディレクトリに含たれるファむルは、ただ圧瞮されおいないRawデヌタが含たれおいる
    • このため、通垞のブロックファむルよりかなり倧きい
  • Prometheusは最䜎3぀のWALファむルを保持しおいる
    • 高トラフィックなサヌバヌでは、少なくずも2時間分のRawデヌタを保存する必芁があるため、3぀を超えるWALファむルができるこずがある

で、ドキュメントに曞かれおいるディレクトリ構造がこちら。ここたで登堎した芁玠が曞かれおいる感じですね。

./data/01BKGV7JBM69T2G1BGBGM6KB12
./data/01BKGV7JBM69T2G1BGBGM6KB12/meta.json
./data/01BKGTZQ1SYQJTR4PB43C8PD98
./data/01BKGTZQ1SYQJTR4PB43C8PD98/meta.json
./data/01BKGTZQ1SYQJTR4PB43C8PD98/index
./data/01BKGTZQ1SYQJTR4PB43C8PD98/chunks
./data/01BKGTZQ1SYQJTR4PB43C8PD98/chunks/000001
./data/01BKGTZQ1SYQJTR4PB43C8PD98/tombstones
./data/01BKGTZQ1HHWHV8FBJXW1Y3W0K
./data/01BKGTZQ1HHWHV8FBJXW1Y3W0K/meta.json
./data/01BKGV7JC0RY8A6MACW02A2PJD
./data/01BKGV7JC0RY8A6MACW02A2PJD/meta.json
./data/01BKGV7JC0RY8A6MACW02A2PJD/index
./data/01BKGV7JC0RY8A6MACW02A2PJD/chunks
./data/01BKGV7JC0RY8A6MACW02A2PJD/chunks/000001
./data/01BKGV7JC0RY8A6MACW02A2PJD/tombstones
./data/wal/00000000
./data/wal/00000001
./data/wal/00000002

より詳现な内容を知りたければ、TSDBのドキュメントぞ。

tsdb/README.md at v0.7.1 · prometheus/tsdb · GitHub

ちなみに、起動盎埌のdataディレクトリの䞭身は、こんな感じです。

$ find data -type f
data/wal/00000000
data/lock

lockずいうファむルは出おきおいたせんでしたね。

$ ls -l data/lock 
-rw-r--r-- 1 xxxxx xxxxx 0 May  2 10:51 data/lock

0バむトのファむルです。

このファむルは、文字通り排他に䜿うファむルのようで、すでにPrometheusが起動した状態で、リッスンポヌトを
倉えお起動したりしようずするず、ロックが取れずに起動に倱敗したす。

$ ./prometheus --web.listen-address="0.0.0.0:9091"

...

level=error ts=2019-05-02T10:53:06.753Z caller=main.go:717 err="opening storage failed: lock DB directory: resource temporarily unavailable"

https://github.com/prometheus/prometheus/blob/v2.9.2/vendor/github.com/prometheus/tsdb/db.go#L280-L283

先に進みたしょう。

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

ロヌカルストレヌゞの制限

ロヌカルストレヌゞの制限は、クラスタ化もされおおらず、たたレプリカも持たないこずです。

なので、ディスクやノヌド障害察しお、耐性がありたせん。スケヌラブルでも耐久性もない、盎近の短呜な
スラむディングりィンドりデヌタずしお扱われるべきです。

耐久性の芁件が厳しくなければ、ロヌカルストレヌゞでも最倧数幎のデヌタを保存できるかもしれない、くらいのこずが
曞かれおいたす 。

このあたりのこずから、ロヌカルストレヌゞのスケヌラビリティず耐久性に぀いおの課題を解決するために、リモヌトの
ストレヌゞシステムず統合する仕組みがある、ずいうこずみたいです。

Remote storage integrations

ロヌカルストレヌゞに関するオプション

ストレヌゞに関するドキュメントの以䞋の郚分に、ストレヌゞに関しお指定できるオプションが曞かれおいたす。

Operational aspects

Prometheus自身のヘルプから、「storage」を含むオプションを衚瀺しおみるず、

$ ./prometheus -h 2>&1 | grep storage
      --storage.tsdb.path="data/"  
                                 Base path for metrics storage.
      --storage.tsdb.retention=STORAGE.TSDB.RETENTION  
                                 storage. This flag has been deprecated, use
                                 "storage.tsdb.retention.time" instead
      --storage.tsdb.retention.time=STORAGE.TSDB.RETENTION.TIME  
                                 How long to retain samples in storage. When
                                 "storage.tsdb.retention". If neither this flag
                                 nor "storage.tsdb.retention" nor
                                 "storage.tsdb.retention.size" is set, the
      --storage.tsdb.retention.size=STORAGE.TSDB.RETENTION.SIZE  
      --storage.tsdb.no-lockfile  
      --storage.tsdb.allow-overlapping-blocks  
      --storage.remote.flush-deadline=<duration>  
      --storage.remote.read-sample-limit=5e7  
      --storage.remote.read-concurrent-limit=10  

「--storage.remote.〜」に぀いおは、リモヌトストレヌゞシステムずの統合に関するオプションなので、ここでは察象倖。

その他のオプションに぀いお、説明を芋おみたす。

      --storage.tsdb.path="data/"  
                                 Base path for metrics storage.
      --storage.tsdb.retention=STORAGE.TSDB.RETENTION  
                                 [DEPRECATED] How long to retain samples in storage. This flag has been deprecated, use "storage.tsdb.retention.time" instead
      --storage.tsdb.retention.time=STORAGE.TSDB.RETENTION.TIME  
                                 How long to retain samples in storage. When this flag is set it overrides "storage.tsdb.retention". If neither this flag nor
                                 "storage.tsdb.retention" nor "storage.tsdb.retention.size" is set, the retention time defaults to 15d.
      --storage.tsdb.retention.size=STORAGE.TSDB.RETENTION.SIZE  
                                 [EXPERIMENTAL] Maximum number of bytes that can be stored for blocks. Units supported: KB, MB, GB, TB, PB. This flag is experimental and can be
                                 changed in future releases.
      --storage.tsdb.no-lockfile  
                                 Do not create lockfile in data directory.
      --storage.tsdb.allow-overlapping-blocks  
                                 [EXPERIMENTAL] Allow overlapping blocks which in-turn enables vertical compaction and vertical query merge

すでにDeprecatedなオプションは無芖したす。

  • --storage.tsdb.path 
 Prometheusがデヌタを保存する際のベヌスパス。デフォルトは、「data」
  • --storage.tsdb.retention.time 
 叀いデヌタをい぀削陀するかを指定する。デフォルトは、「15d」
  • --storage.tsdb.retention.size 
 実隓的ストレヌゞブロックが最倧で䜿甚できるサむズを指定する
  • --storage.tsdb.no-lockfile 
 dataディレクトリ内に、ロックファむルを䜜成しない
  • --storage.tsdb.allow-overlapping-blocks 
 実隓的オヌバヌラップするブロックを蚱可する。圧瞮、ク゚リヌの瞊方向のマヌゞが可胜になる

「--storage.tsdb.retention.time」のデフォルト倀は15日で、フォヌマットにはy、w、d、h、m、s、msが利甚できたす。

prometheus/db.go at v2.9.2 · prometheus/prometheus · GitHub

https://github.com/prometheus/prometheus/blob/v2.9.2/vendor/github.com/prometheus/common/model/time.go#L192-L208

デヌタの保持期間に関するリテンションポリシヌは時間ずサむズの2぀がありたすが、䜿われるのは最初に動䜜した方だずか。
※サむズはただ実隓的なので、スルヌしたしたが

「--storage.tsdb.allow-overlapping-blocks」に぀いおは、ただ実隓的な感じがするので、スルヌしたす 。

Implement vertical query merging and compaction · Issue #90 · prometheus/tsdb · GitHub

なお、2時間ごずにブロックにたずめられる、ずいうのは、このあたりから来おいる気がしたす。

https://github.com/prometheus/prometheus/blob/v2.9.2/vendor/github.com/prometheus/tsdb/db.go#L51

ずころでですね、PrometheusのWeb Consoleから「Status」→「Command-Line Flags」を芋るず、もう少し指定できそうな
オプションが倚いように芋えるのですが 。

f:id:Kazuhira:20190502222000p:plain

今回は、ずりあえず深远いしない 。

ロヌカルストレヌゞで必芁ずするディスク容量

Prometheusは、ひず぀のサンプルあたり、1〜2バむトほどを䜿甚するそうです。

なので、Prometheusが芁求するサヌバヌのディスク容量は、以䞋の蚈算匏で算出できたす、ず。

needed_disk_space = retention_time_seconds * ingested_samples_per_second * bytes_per_sample
必芁なディスクサむズ = 保持期間秒 × 秒あたりの取埗サンプル数 * サンプルあたりのバむト数

1秒あたりに取埗するサンプルを小さくするには、取埗する時系列デヌタの数を枛らす収集するタヌゲットを枛らす、
タヌゲットあたりの取埗項目を枛らすか、取埗間隔を長く蚭定するかのどちらかです。

ドキュメントによるず、取埗したデヌタは圧瞮されるため、取埗する項目数を枛らす方が効果的だずか。

なお、ロヌカルストレヌゞが砎損した堎合は、以䞋の察凊になるずか。

  • Prometheusをシャットダりンしお、デヌタディレクトリを削陀するこれが最善らしい
    • 圓然、党デヌタを倱う
  • 個々のブロックディレクトリを削陀する
    • 削陀したブロックに含たれる、2時間のデヌタは倱う

どちらにせよ、Prometheusのロヌカルストレヌゞは長期間のデヌタ保存を意図しおいないこずがドキュメントでは匷調されおいたす。

デヌタの保持期間を指定しおみる

それでは、デヌタの保持期間を短めにしお、動䜜を確認しおみたしょう。

以䞋のような、デヌタの取埗間隔を短めにしたPrometheusの蚭定ファむルを甚意し、起動。
prometheus.yml

global:
  scrape_interval:     1s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 1s # Evaluate rules every 15 seconds. The default is every 1 minute.

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
    - targets: ['localhost:9090']

デヌタの取埗察象は、デフォルト自分自身のたたです。

起動オプションずしお、早めに消えるこずを確認したくお「--storage.tsdb.retention.time」を3分に蚭定したした。
あず、「--storage.tsdb.min-block-duration」を指定しおいたすが、なんでこれを付けたかはたた埌で 。

$ ./prometheus --storage.tsdb.retention.time 3m --storage.tsdb.min-block-duration 1m
level=info ts=2019-05-02T14:09:07.183Z caller=main.go:321 msg="Starting Prometheus" version="(version=2.9.2, branch=HEAD, revision=d3245f15022551c6fc8281766ea62db4d71e2747)"

Web Consoleで、起動オプションを認識しおいるこずを確認。

f:id:Kazuhira:20190502231638p:plain

ずりあえず、Web ConsoleでCPU䜿甚時間process_cpu_seconds_totalを衚瀺。10分間の衚瀺で芋おいたす。

f:id:Kazuhira:20190502231018p:plain

1分経過するず、こんなログが出力され

level=info ts=2019-05-02T14:10:44.219Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806153112 maxt=1556806200000 ulid=01D9WE45RQ73CF18Y6J2BPMN1Q duration=100.343317ms
level=info ts=2019-05-02T14:10:44.237Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.785374ms

ブロックができたす。

$ find data -type f
data/wal/00000000
data/lock
data/01D9WE45RQ73CF18Y6J2BPMN1Q/meta.json
data/01D9WE45RQ73CF18Y6J2BPMN1Q/index
data/01D9WE45RQ73CF18Y6J2BPMN1Q/tombstones
data/01D9WE45RQ73CF18Y6J2BPMN1Q/chunks/000001

このログが4回出力されるたでは、ブロックディレクトリが远加されおいきたす。

level=info ts=2019-05-02T14:10:44.219Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806153112 maxt=1556806200000 ulid=01D9WE45RQ73CF18Y6J2BPMN1Q duration=100.343317ms
level=info ts=2019-05-02T14:10:44.237Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.785374ms
level=info ts=2019-05-02T14:11:30.196Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806200000 maxt=1556806260000 ulid=01D9WE5JP7Y6FFGZMKKS1KK2AD duration=77.507689ms
level=info ts=2019-05-02T14:11:30.217Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.549613ms
level=info ts=2019-05-02T14:12:30.229Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806260000 maxt=1556806320000 ulid=01D9WE7D97CMB7R8RS12G9E9YW duration=109.711593ms
level=info ts=2019-05-02T14:12:30.251Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.421509ms
level=info ts=2019-05-02T14:13:30.197Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806320000 maxt=1556806380000 ulid=01D9WE97W9WEKZCQ0957KVH2GX duration=75.948389ms
level=info ts=2019-05-02T14:13:30.215Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.492116ms

こんな感じに。

$ find data -type f
data/wal/00000000
data/01D9WE7D97CMB7R8RS12G9E9YW/meta.json
data/01D9WE7D97CMB7R8RS12G9E9YW/index
data/01D9WE7D97CMB7R8RS12G9E9YW/tombstones
data/01D9WE7D97CMB7R8RS12G9E9YW/chunks/000001
data/lock
data/01D9WE45RQ73CF18Y6J2BPMN1Q/meta.json
data/01D9WE45RQ73CF18Y6J2BPMN1Q/index
data/01D9WE45RQ73CF18Y6J2BPMN1Q/tombstones
data/01D9WE45RQ73CF18Y6J2BPMN1Q/chunks/000001
data/01D9WE5JP7Y6FFGZMKKS1KK2AD/meta.json
data/01D9WE5JP7Y6FFGZMKKS1KK2AD/index
data/01D9WE5JP7Y6FFGZMKKS1KK2AD/tombstones
data/01D9WE5JP7Y6FFGZMKKS1KK2AD/chunks/000001
data/01D9WE97W9WEKZCQ0957KVH2GX/meta.json
data/01D9WE97W9WEKZCQ0957KVH2GX/index
data/01D9WE97W9WEKZCQ0957KVH2GX/tombstones
data/01D9WE97W9WEKZCQ0957KVH2GX/chunks/000001

f:id:Kazuhira:20190502231415p:plain

ここで、5回目のコンパクションが起こるず

level=info ts=2019-05-02T14:10:44.219Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806153112 maxt=1556806200000 ulid=01D9WE45RQ73CF18Y6J2BPMN1Q duration=100.343317ms
level=info ts=2019-05-02T14:10:44.237Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.785374ms
level=info ts=2019-05-02T14:11:30.196Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806200000 maxt=1556806260000 ulid=01D9WE5JP7Y6FFGZMKKS1KK2AD duration=77.507689ms
level=info ts=2019-05-02T14:11:30.217Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.549613ms
level=info ts=2019-05-02T14:12:30.229Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806260000 maxt=1556806320000 ulid=01D9WE7D97CMB7R8RS12G9E9YW duration=109.711593ms
level=info ts=2019-05-02T14:12:30.251Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.421509ms
level=info ts=2019-05-02T14:13:30.197Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806320000 maxt=1556806380000 ulid=01D9WE97W9WEKZCQ0957KVH2GX duration=75.948389ms
level=info ts=2019-05-02T14:13:30.215Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.492116ms
level=info ts=2019-05-02T14:14:30.248Z caller=compact.go:499 component=tsdb msg="write block" mint=1556806380000 maxt=1556806440000 ulid=01D9WEB2F4SWD5FDP5EBV7BD0E duration=132.373486ms
level=info ts=2019-05-02T14:14:30.270Z caller=head.go:540 component=tsdb msg="head GC completed" duration=1.201336ms

ブロックディレクトリが増えなくなりたす。「01D9WE45RQ73CF18Y6J2BPMN1Q」ずいう名前のディレクトリがいなくなりたした。

$ find data -type f
data/01D9WEB2F4SWD5FDP5EBV7BD0E/meta.json
data/01D9WEB2F4SWD5FDP5EBV7BD0E/index
data/01D9WEB2F4SWD5FDP5EBV7BD0E/tombstones
data/01D9WEB2F4SWD5FDP5EBV7BD0E/chunks/000001
data/wal/00000000
data/01D9WE7D97CMB7R8RS12G9E9YW/meta.json
data/01D9WE7D97CMB7R8RS12G9E9YW/index
data/01D9WE7D97CMB7R8RS12G9E9YW/tombstones
data/01D9WE7D97CMB7R8RS12G9E9YW/chunks/000001
data/lock
data/01D9WE5JP7Y6FFGZMKKS1KK2AD/meta.json
data/01D9WE5JP7Y6FFGZMKKS1KK2AD/index
data/01D9WE5JP7Y6FFGZMKKS1KK2AD/tombstones
data/01D9WE5JP7Y6FFGZMKKS1KK2AD/chunks/000001
data/01D9WE97W9WEKZCQ0957KVH2GX/meta.json
data/01D9WE97W9WEKZCQ0957KVH2GX/index
data/01D9WE97W9WEKZCQ0957KVH2GX/tombstones
data/01D9WE97W9WEKZCQ0957KVH2GX/chunks/000001

この結果、最初の時間のデヌタがなくなりたす。「01D9WE45RQ73CF18Y6J2BPMN1Q」ずいうのは、最初に䜜られた
ディレクトリでした。

f:id:Kazuhira:20190502231541p:plain

ずいうわけで、「--storage.tsdb.retention.time」で指定した保持期間を越えたデヌタは削陀されおいるこずが確認できたした。

ずころで、今回、起動オプションに「--storage.tsdb.retention.time」だけではなくお「--storage.tsdb.min-block-duration」も
指定したした。

$ ./prometheus --storage.tsdb.retention.time 3m --storage.tsdb.min-block-duration 1m

「--storage.tsdb.min-block-duration」を指定したこずで、ブロックの範囲が1分になっおいたす。

最初、以䞋のように「--storage.tsdb.retention.time」を指定しただけだずデヌタがたったく消えず、「もしかしおWALにいる間の
デヌタは察象に入らないのでは」ず思い、倉曎に至りたした。

$ ./prometheus --storage.tsdb.retention.time 3m

぀たり、長時間埅぀のが嫌で、極端に短い時間をretentionに蚭定したのが完党に裏目に出たようです。

実際、削陀察象はブロック単䜍のようです。

https://github.com/prometheus/prometheus/blob/v2.9.2/vendor/github.com/prometheus/tsdb/db.go#L670

ブロックディレクトリ内のmeta.jsonを芋るず、minTimeずmaxTimeで、どの時間の範囲のデヌタが含たれおいるか確認するこずが
できたす。
data/01D9WEEQN5CH9F53GAFCN3G14E/meta.json

{
    "ulid": "01D9WEEQN5CH9F53GAFCN3G14E",
    "minTime": 1556806500000,
    "maxTime": 1556806560000,
    "stats": {
        "numSamples": 27120,
        "numSeries": 452,
        "numChunks": 452,
        "numBytes": 77220
    },
    "compaction": {
        "level": 1,
        "sources": [
            "01D9WEEQN5CH9F53GAFCN3G14E"
        ]
    },
    "version": 1
}

ここからわかるこずは、「--storage.tsdb.min-block-duration」を蚭定するこずはそうないかもしれたせんが、
「--storage.tsdb.retention.time」はブロックディレクトリで持぀範囲デフォルト2時間の倍数でなければ意味がない
ずいうこずですね。

芚えおおきたしょう。

いい確認になりたした。