# Prometheus Advent Calendar 2017 7日目

の記事です

# Prometheusのストレージについて

Prometheus serverのローカルストレージはクラスタリングやレプリケートされません。なので、耐障害性や長期保存を実現する構成を検討するとRemote storage integrationを導入したり、Prometheusを複数台同時稼働させてヒストリ/トレンド用のサーバを別に用意したり、方法はいくつかあると思いますが、S3にデータを保管できれば、少なくともクラウド環境においては、Prometheusのストレージが抱える課題は解決するのでは?(パフォーマンスは一旦置いておく)と思って、S3に保存できるのかどうかを試してみました。

結論

だめでした。

だめでしたが、そこにいたる経過だけでも残しておこうと本記事を書きます。

検索しても同様な記事が出てこないのが、そんなのはなからダメに決まっているから誰もやっていない、のか、たまたま誰も記事に残していなかったから、のどちらなのかな。

# やったこと

  • Prometheus serverの導入
  • goofysの導入
  • S3バケットの作成
  • EC2インスタンスにS3バケットをマウント
  • --storage.tsdb.pathにマウントポイントを指定

# goofysの導入からマウントまで

goofysを導入してマウントさせるところまでは、情報が豊富なので調べながら実施。
テスト用に test-for-prometheus という名前のバケットを作成しています。

パッケージのインストール
$ sudo yum install golang fuse
インストール
$ export GOPATH=$HOME/go
$ echo $GOPATH
$ go get github.com/kahing/goofys
$ go install github.com/kahing/goofys
マウント
$ mkdir ~/mount-goofys
$ ./go/bin/goofys test-for-prometheus ~/mount-goofys
$ df -hT
ファイルシス        タイプ   サイズ  使用  残り 使用% マウント位置
/dev/xvda2          xfs         10G  4.3G  5.8G   43% /
devtmpfs            devtmpfs   471M     0  471M    0% /dev
tmpfs               tmpfs      496M     0  496M    0% /dev/shm
tmpfs               tmpfs      496M   13M  483M    3% /run
tmpfs               tmpfs      496M     0  496M    0% /sys/fs/cgroup
tmpfs               tmpfs      100M     0  100M    0% /run/user/1000
test-for-prometheus fuse       1.0P     0  1.0P    0% /home/ec2-user/mount-goofys

作成したバケットにマウントできていることが確認できました。

# Prometheusを起動してみた

EC2 にS3をマウントした状態で、ストレージのパスにマウントポイントを指定してPrometheus を起動します。

パスは/home/ec2-user/goofysです。

Prometheusの起動
./prometheus --storage.tsdb.path=/home/ec2-user/goofys &
起動後のメッセージ
level=info ts=2017-12-04T15:22:44.518225058Z caller=main.go:215 msg="Starting Prometheus" version="(version=2.0.0, branch=HEAD, revision=0a74f98628a0463dddc90528220c94de5032d1a0)"
level=info ts=2017-12-04T15:22:44.518333843Z caller=main.go:216 build_context="(go=go1.9.2, user=root@615b82cb36b6, date=20171108-07:11:59)"
level=info ts=2017-12-04T15:22:44.518368849Z caller=main.go:217 host_details="(Linux 3.10.0-693.5.2.el7.x86_64 #1 SMP Fri Oct 13 10:46:25 EDT 2017 x86_64 ip-10-0-0-253.ap-northeast-1.compute.internal (none))"
level=info ts=2017-12-04T15:22:44.521532251Z caller=web.go:380 component=web msg="Start listening for connections" address=0.0.0.0:9090
level=info ts=2017-12-04T15:22:44.525475101Z caller=main.go:314 msg="Starting TSDB"
level=info ts=2017-12-04T15:22:44.527198442Z caller=targetmanager.go:71 component="target manager" msg="Starting target manager..."
level=error ts=2017-12-04T15:22:45.000988247Z caller=main.go:323 msg="Opening storage failed" err="open DB in /home/ec2-user/goofys: Lockfile created, but doesn't exist"

[1]+  終了 1                ./prometheus --storage.tsdb.path=/home/ec2-user/goofys
エラーメッセージ抜粋
msg="Opening storage failed" err="open DB in /home/ec2-user/goofys: Lockfile created, but doesn't exist"

lockfileに関するエラーがでました。エラーの根本原因を解消する方法がわからなかったので、lockfileを生成しないオプションをつけて回避してみました。

no-lockfileオプションをつけてPrometheusを実行
./prometheus --storage.tsdb.path=/home/ec2-user/goofys --storage.tsdb.no-lockfile

回避実行後、問題なく動き出したのでいけるかもと思ったのですが、しばらくしてcompaction処理に関するエラーが出力されました。やっぱりだめでした。

起動後のエラー
level=info ts=2017-12-04T15:17:31.605759686Z caller=compact.go:361 component=tsdb msg="compact blocks" count=1 mint=1512400200000 maxt=1512400500000
level=error ts=2017-12-04T15:17:33.361261637Z caller=db.go:260 component=tsdb msg="compaction failed" err="persist head block: rename block dir: rename /home/ec2-user/goofys/01C0H1N1AN3A5X0MK74PRSAY9M.tmp /home/ec2-user/goofys/01C0H1N1AN3A5X0MK74PRSAY9M: directory not empty"
level=info ts=2017-12-04T15:17:34.361568694Z caller=compact.go:361 component=tsdb msg="compact blocks" count=1 mint=1512400200000 maxt=1512400500000
level=error ts=2017-12-04T15:17:35.814231038Z caller=db.go:260 component=tsdb msg="compaction failed" err="persist head block: rename block dir: rename /home/ec2-user/goofys/01C0H1N40SMRS10YJMVJPWPJPM.tmp /home/ec2-user/goofys/01C0H1N40SMRS10YJMVJPWPJPM: directory not empty"
level=info ts=2017-12-04T15:17:37.814513215Z caller=compact.go:361 component=tsdb msg="compact blocks" count=1 mint=1512400200000 maxt=1512400500000
level=error ts=2017-12-04T15:17:38.578344691Z caller=db.go:260 component=tsdb msg="compaction failed" err="persist head block: rename block dir: rename /home/ec2-user/goofys/01C0H1N7CP6E80WWEJK8N2D7KY.tmp /home/ec2-user/goofys/01C0H1N7CP6E80WWEJK8N2D7KY: directory not empty"
level=info ts=2017-12-04T15:17:42.580103661Z caller=compact.go:361 component=tsdb msg="compact blocks" count=1 mint=1512400200000 maxt=1512400500000
level=error ts=2017-12-04T15:17:43.965570722Z caller=db.go:260 component=tsdb msg="compaction failed" err="persist head block: rename block dir: rename /home/ec2-user/goofys/01C0H1NC1M4QWZC9WSR0BCWB2H.tmp /home/ec2-user/goofys/01C0H1NC1M4QWZC9WSR0BCWB2H: directory not empty"
level=info ts=2017-12-04T15:17:51.965865517Z caller=compact.go:361 component=tsdb msg="compact blocks" count=1 mint=1512400200000 maxt=1512400500000
level=error ts=2017-12-04T15:17:53.678202798Z caller=db.go:260 component=tsdb msg="compaction failed" err="persist head block: rename block dir: rename /home/ec2-user/goofys/01C0H1NN6XEEK8NBCYX0EQFXW6.tmp /home/ec2-user/goofys/01C0H1NN6XEEK8NBCYX0EQFXW6: directory not empty"
level=info ts=2017-12-04T15:18:09.678508478Z caller=compact.go:361 component=tsdb msg="compact blocks" count=1 mint=1512400200000 maxt=1512400500000
level=error ts=2017-12-04T15:18:10.986053949Z caller=db.go:260 component=tsdb msg="compaction failed" err="persist head block: rename block dir: rename /home/ec2-user/goofys/01C0H1P6GENM7ZV34AQ1FNWC8P.tmp /home/ec2-user/goofys/01C0H1P6GENM7ZV34AQ1FNWC8P: directory not empty"

compaction処理の中で、blockディレクトリをrenameする処理が失敗しているよう。

compaction処理が正常に走らないのですが、Prometheus自体は動き続けていますので生データはどんどん蓄積されていきます。compactionされないtmpディレクトリが延々と生成されます。ディレクトリ名にtmpとついているものの、中身はいつものblockディレクトリのそれと同じであり、データ自体も問題ないようです(クエリを投げて、それらしい値が返ってきているので)。内部的には、tmpというblockを生成して、リネームしているんだなというのがわかりました。

block名.tmp -> block名

S3のディレクトリ(オブジェクト)は、中にファイルが存在しているとmvできない仕様ということで、これはもうどうしようもないなという感じでした。どなたかもし解決法ご存知でしたら教えてください。

block名.tmpディレクトリたち
drwxr-xr-x. 2 ec2-user ec2-user   4096 124 16:37 01C0H0YA135H8P219CH1RXWWHP.tmp
drwxr-xr-x. 2 ec2-user ec2-user   4096 124 16:37 01C0H105VT3VJP7TYC3S6H9XXW.tmp
drwxr-xr-x. 2 ec2-user ec2-user   4096 124 16:37 01C0H121PKN8WV8G06Q0DJ08X6.tmp
drwxr-xr-x. 2 ec2-user ec2-user   4096 124 16:37 01C0H13XNQYMZX82WX5H477HFN.tmp
drwxr-xr-x. 2 ec2-user ec2-user   4096 124 16:37 01C0H15T7FFQPKTTAC5BHDRD0Z.tmp
drwxr-xr-x. 2 ec2-user ec2-user   4096 124 16:37 wal