VictoriaMetricsを使ってみた話

#はじめに
この記事は、MicroAd Advent Calendar 2020の11日目の記事です。

Prometheusのメトリクス長期保管を目的とし、LongtermStorageとしてVictoriaMetricsを導入した話を書きます。700-900台、2000サービスの監視で使用してそろそろ4ヶ月になります。今日はその経緯と感想などをお話します。

#背景
Prometheus自体には水平にスケールするようなクラスタ機能は無く、単体ではメトリクスをローカルディスクに保管するしかありません。ローカルに積めるディスクには限りがあり、メトリクスの長期保管はし辛いものがあります。
それを補うものとして、Prometheusにはリモート書き出し先を指定できる機能（remote_write）があり、色々なストレージに対応しています。長期保管には外部のストレージを使うべし、クラスタリングもそっちでやってね、という事ですね。

#弊社の運用と色々な事情
弊社のオンプレサーバの監視では、１年半くらいメトリクスを保持したいという要件があります。
そこで、Prometheusサーバのディスクがいっぱいになる度にPrometheusとGrafanaのセットを増やす運用をしてきました。期間AのグラフはGrafana Aを、期間BのグラフはGrafana Bを見る、といった具合です。１年弱ちまちまやってきましたが、監視対象も増え三ヶ月おきにセットを増やす状態に。なかなかの苦行でした。

水平にスケールできるストレージとして、Thanosが良さそうでした。が、弊社ではデータ書き出し先はクラウドではなくオンプレが前提でしたが、当時(2019年初夏）クラウドメインでオンプレ対応が正式版ではなかった（はず）ため、導入は見送りました。[^1]
その後、2020年1月のPrometheus Meetup Tokyo #3でコロプラの入江さんが紹介[^2]されていたVictoriaMetricsに希望を見出しました。オンプレ前提で性能面、安定性も定評があり、構成もシンプル。これを使えば、Grafanaを1本に統合し外部ストレージさえスケールしていけば良いというまともな運用に切り替えられる！と心踊ったのを覚えています。[^3]

#こんな構成にした
とてもシンプルです。VictoriaMetrics（以降、VM）のクラスタ版[^4]を使い下図のようにしています。
各サーバでは各コンポーネントがdockerコンテナで動いています。Kubernetesは稼働しておらず、docker-composeで起動しています。
vmstorageというVM独自のストレージに、vminsertサーバが書き込みを行い、vmselectサーバが参照を行います。vminsert,vmselect共にLVS配下に置き、それぞれVIPを持たせています。
Prometheusからの書き込みも、Grafanaからの参照もこのVIP宛に行わせています。
スクレイプとAlertは従来通りPrometheusとAlertmanagerで行なっています。[^5]

![スクリーンショット 2020-12-07 13.44.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209746/818cb6f0-365e-620c-6a6c-26b2a671f098.png)



#稼働させてみて気づいた事

### 1.圧縮率が高い
Prometheusに蓄積してきた過去分のメトリクスデータをvmctl[^6]コマンドでVMに移行しました。
Prometheusのデータで1TBほどのメトリクスを格納したはずが、vmstorageの使用容量は120GB程度でした。メトリクスデータに欠損はなさそうで、念の為開発者に問い合わせたところ圧縮率は10%ほどになる、という話でした。確かに、Grafanaに[VMのダッシュボード](https://grafana.com/grafana/dashboards/11831)を追加して見たところ、「Compression Ratio」の項目は13-14%を上下している状態です。
Thanosでは過去のメトリクスをダウンサイジングする機能がありますがVMにはありません。その理由は、圧縮率の高さにある、と公式ドキュメントにあるのもなるほど頷けます。

### 2.vmstorageのクラスタ的なストレージとしての機能は限定的
HDFSなどのクラスタに慣れてしまうと、ノードごとのデータ配置のリバランスや、ノード構成変更時や障害時のレプリカ自動コピーの機能を期待してしまいますが、vmstorageにはそういった機能はありません。
あくまで、ノード横断で読み書きをできるクラスタ。下記の動きに特化しているクラスタ、といった理解です。

- read:　vmselectが全vmstorageにクエリを投げる。
- write:　vminsertがコンシステントハッシュングで選定したvmstorageノードにデータを格納

つまりvmstorageに格納済みのデータの面倒は行ってはくれないので、運用でカバーする必要があります。本格稼動前にシナリオを想定しないといけません。
あるノードのディスクがいっぱいになった場合は、リバランスはできないので、vmselectからの参照は継続するがvminsertからのデータ書き込み対象からは外す、という対応をする方法をとります。
レプリカ数の設定は、ノード障害時の対応方法を鑑みて検討する必要があります。弊社では、レプリカ数２として、障害時には健全なノードの丸々コピーを作成する方針です。（要件次第ですが、レプリ数３ならそこまでの対応は不要かもしれません。）


### 3.バージョンアップ時の考慮
VMのバージョンアップは、マイナーバージョンアップであればローリングで可能ですが、そうも行かない場合があります。恥ずかしながら、v1.39.0へのバージョンアップの際、[vmselectとvmstorageとの接続部分に修正](https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/v1.39.0)があり、作業中にGrafanaが見えなくなってしまうという失敗をしました。
全コンポーネントのバージョンを揃える必要があるバージョンアップの場合は、VMクラスタ全停止のタイミングが生じる[^7]ので、（当たり前ですが汗）リリースをよく確認しないといけないですね。

#まとめと反省
導入前は良いことばかりに目が行きますが、実際に使ってみると問題が出るものです。
有り物のSSDを積んだサーバでvmstorageを作成して運用してしまっていますが、新データセンタでの構築時には、もっと大きいHDD搭載のものを使ってノード数を抑えたいと考えています。
ただ、安定性に関しては前評判通りでホッとしています。そして何より、期間ごとのGrafana増殖運用から抜け出せたのが何より幸せです。
今後は、PromQLを拡張したMetricsQLの有効利用もしていきたいと思います。Prometheusの冗長化も賢く行いたい。
課題は尽きません。


[^1]: あと、コンポーネントの多さにビビったのもあります。Cephに対応しているので、オンプレでも現在は使えそうです。ThanosとVictoriaMetricsの比較は記事が多く出ていますね。
[^2]: [「VictoriaMetricsで作る大規模・超負荷システムモニタリング基盤」](https://speakerdeck.com/inletorder/monitoring-platform-with-victoria-metrics)
[^3]: そうこうするうちのコロナ禍です。緊急事態宣言下、昼間は幼子の相手をし夜中に調査や検証をしていました。VMのSlackに入りたての頃、開発者から様子伺いのDMが来たり、QAしたり。VMは心の支えでした。
[^4]: クラスタ版とシングルノード版があります。軽く動作を見るのにはシングルノード版が便利です。
[^5]: VictoriaMetricsは両者の代替としてそれぞれ、vmagent,vmalertというコンポーネントも出ていますが、もう少し成熟を待ちたいと思います。
[^6]: [VictoriaMetrics/vmctl](https://github.com/VictoriaMetrics/vmctl)
[^7]: それもあり、ScrapeとAlertはVMのコンポーネントに乗り換えるのは慎重になります。現構成であれば、VMが全停止していてもScrapeは継続しメトリクスはPrometheus側に蓄積（短期間ですが）されますし、Alert時はAlertmanagerに通知するだけなのでAlertが停止することはありません。