VictoriaMetricsのKey conceptsをササッとなぞって理解を深める

VictoriaMetricsのKey conceptsをササッとなぞって理解を深める

こんにちは、システムエンジニアの kouki です。

この記事では VictoriaMetrics のドキュメントに掲載されている Key concepts - VictoriaMetrics をハンズオン形式にまとめてみました。記事を書くに至ったモチベーションは下記の通りです。

  • VictoriaMetrics に入門してみたいけど、日本語で記述されているチュートリアル的なものがない (2022年12月現在)
  • 自身でデータを登録して、自身でクエリを投げる形式のチュートリアルが Web 上に見当たらなかった
  • Key concepts - VictoriaMetrics は画像と共に解説されていて分かりやすいが、手元で試すには若干の試行錯誤が必要だった

ちなみに Key concepts では下記のような画像と共に VictoriaMetrics の挙動が解説されているので、非常に理解の助けになるドキュメントだと思います。

Key concepts - VictoriaMetrics に掲載されている解説画像

Key concepts を触ってみる

事前準備

今回のチュートリアルを実施するにあたって、下記の環境は構築済みという前提でお話します。

  • docker コマンドを打てる環境であること ( docker run ... など)
  • curl コマンドがインストール済みであること
  • (任意) jq コマンドがインストール済みであること

VictoriaMetrics を docker コマンドで立ち上げる

Quick start - VictoriaMetrics を参考に -retentionPeriod=100y オプションを付与して、手元に VictoriaMetrics を立ち上げます。

docker pull victoriametrics/victoria-metrics:v1.85.3
docker run -it --rm -v `pwd`/victoria-metrics-data:/victoria-metrics-data -p 8428:8428 victoriametrics/victoria-metrics:v1.85.3 -retentionPeriod=100y

docker image のタグは v1.85.3 を指定しています。(latest だと記事との齟齬が出る可能性があるため)

-retentionPeriod というコマンドオプションはVictoriaMetrics のドキュメントに記載されている通り、データの保持期間を指定するものです。デフォルトでは1ヵ月(それ以降は削除される)ですが、今回のチュートリアルでは1ヵ月以上前のデータを登録する予定のため、それ以上の値として 100y を指定しています。(保持期間に「無限」という指定はできないので、100y と指定する旨は VictoriaMetrics の README にも記載されています)

retention for stored data. Older data is automatically deleted. Default retention is 1 month. See the Retention section for more details.

ブラウザで http://localhost:8428/ が閲覧できることを確認します。

VictoriaMetrics VMUIの画面

VictoriaMetrics にデータを登録する

Key concepts · VictoriaMetrics にある「Query data」のセクションのデータを VictoriaMetrics に登録します。

ドキュメントでは下記のようなデータが記載されています。左から「メトリクス名」「データの値」「タイムスタンプ(Unix Time Stamp(ミリ秒)」となっています。

注意点として、コメントのような形で「# 2022-05-10 10:00:00」と記載されていますが、UTC で確認すると 2022-05-10 08:00:00 (マイナス2時間) となります。ここ以降のコマンドは公式ドキュメントに記載されている時間からマイナス 2 時間した時刻を基準にしていきます。

foo_bar 1.00 1652169600000 # 2022-05-10 10:00:00
foo_bar 2.00 1652169660000 # 2022-05-10 10:01:00
foo_bar 3.00 1652169720000 # 2022-05-10 10:02:00
foo_bar 5.00 1652169840000 # 2022-05-10 10:04:00, one point missed
foo_bar 5.50 1652169960000 # 2022-05-10 10:06:00, one point missed
foo_bar 5.50 1652170020000 # 2022-05-10 10:07:00
foo_bar 4.00 1652170080000 # 2022-05-10 10:08:00
foo_bar 3.50 1652170260000 # 2022-05-10 10:11:00, two points missed
foo_bar 3.25 1652170320000 # 2022-05-10 10:12:00
foo_bar 3.00 1652170380000 # 2022-05-10 10:13:00
foo_bar 2.00 1652170440000 # 2022-05-10 10:14:00
foo_bar 1.00 1652170500000 # 2022-05-10 10:15:00
foo_bar 4.00 1652170560000 # 2022-05-10 10:16:00

curl コマンドで /api/v1/import エンドポイントに対してデータを登録します。

curl -d '{"metric":{"__name__":"foo_bar"},"values":[1.0,2.0,3.0,5.0,5.5,5.5,4.0,3.5,3.25,3.0,2.0,1.0,4.0],"timestamps":[1652169600000,1652169660000,1652169720000,1652169840000,1652169960000,1652170020000,1652170080000,1652170260000,1652170320000,1652170380000,1652170440000,1652170500000,1652170560000]}' -X POST 'http://localhost:8428/api/v1/import'

スペース区切りのテキストから curl コマンドの文字列を出力する簡単な ruby スクリプトを用意して実施しました。このスクリプトは上記の curl コマンドを出力するだけですので、あまり重要ではないので読み飛ばしても問題ありません。

require 'json'

# VictoriaMetrics に提示されているサンプルデータ
# UTC では 2022-05-10 08:00:00 から始まるので注意
# 変換に利用したサイト refs: https://www.unixtimestamp.com/index.php
# データの引用元 refs: https://docs.victoriametrics.com/keyConcepts.html#query-data
vm_sample_data = <<~EOS
  foo_bar 1.00 1652169600000 # 2022-05-10 10:00:00
  foo_bar 2.00 1652169660000 # 2022-05-10 10:01:00
  foo_bar 3.00 1652169720000 # 2022-05-10 10:02:00
  foo_bar 5.00 1652169840000 # 2022-05-10 10:04:00, one point missed
  foo_bar 5.50 1652169960000 # 2022-05-10 10:06:00, one point missed
  foo_bar 5.50 1652170020000 # 2022-05-10 10:07:00
  foo_bar 4.00 1652170080000 # 2022-05-10 10:08:00
  foo_bar 3.50 1652170260000 # 2022-05-10 10:11:00, two points missed
  foo_bar 3.25 1652170320000 # 2022-05-10 10:12:00
  foo_bar 3.00 1652170380000 # 2022-05-10 10:13:00
  foo_bar 2.00 1652170440000 # 2022-05-10 10:14:00
  foo_bar 1.00 1652170500000 # 2022-05-10 10:15:00
  foo_bar 4.00 1652170560000 # 2022-05-10 10:16:00
EOS

json_for_victoriametrics = {
  "metric" => {
    "__name__" => nil
  },
  "values" => [],
  "timestamps" => []
}

vm_sample_data.lines.each do |line|
  name, value, timestamp_milisecs = line.split(' ')
  json_for_victoriametrics['metric']['__name__'] = name if json_for_vm['metric']['__name__'].nil?
  json_for_victoriametrics['values'].push(value.to_f)
  json_for_victoriametrics['timestamps'].push(timestamp_milisecs.to_i)
end

puts "curl -d '#{json_for_vm.to_json}' -X POST 'http://localhost:8428/api/v1/import'"

データが登録できたか確認する

先述した curl コマンドによってデータが登録できたか確認しましょう。最初のデータの時刻は「注意点」に記載した通り、マイナス 2 時間した値のため 2022-05-10T08:00:00.000Z を指定します。

curl -s "http://localhost:8428/api/v1/query?query=foo_bar&time=2022-05-10T08:00:00.000Z" | jq

{
  "status": "success",
  "data": {
    "resultType": "vector",
    "result": [
      {
        "metric": {
          "__name__": "foo_bar"
        },
        "value": [
          1652169600,
          "1"
        ]
      }
    ]
  }
}

Key concepts の Query data をなぞってみる

Instant query

早速 Key concepts の Query data を元に触っていきましょう。あらかじめ、Key concepts の Query data のページを開いておくとスムーズに読めると思います。

まずは Instant query から試していきます。マイナス 2 時間した時刻でクエリを投げてみます。

curl -s "http://localhost:8428/api/v1/query?query=foo_bar&time=2022-05-10T08:03:00.000Z" | jq

{
  "status": "success",
  "data": {
    "resultType": "vector",
    "result": [
      {
        "metric": {
          "__name__": "foo_bar"
        },
        "value": [
          1652169780,
          "3"
        ]
      }
    ]
  }
}

ここでは 「登録したデータの中に 2022-05-10T08:03:00.00 のデータは無いにも関わらず、3 という値がレスポンスされた」 がポイントです。(元のデータでいうと # 2022-05-10 10:02:00# 2022-05-10 10:04:00 の間)

VictoriaMetrics Instant Query の画像

詳細は公式の解説を読んでみてください。

Range query

次は Range query を試してみます。

curl "http://localhost:8428/api/v1/query_range?query=foo_bar&step=1m&start=2022-05-10T07:59:00.000Z&end=2022-05-10T08:17:00.000Z" | jq

{
  "status": "success",
  "data": {
    "resultType": "matrix",
    "result": [
      {
        "metric": {
          "__name__": "foo_bar"
        },
        "values": [
          [
            1652169600,
            "1"
          ],
          [
            1652169660,
            "2"
          ],
          [
            1652169720,
            "3"
          ],
          (省略)
        ]
      }
    ]
  }
}

意図した値が返ってくることが確認できると思います。

ここでも注意点ですが、 Range query に記載されている JSON のレスポンスの中に 7 という数値が含まれていますが、こちらはおそらく 5 が正しいものだと思われます。

解説文にも図と共に下記のように記載されています。

Key concepts - VictoriaMetrics に掲載されている解説画像

ephemeral data point always repeats the left closest raw sample (see red arrow on the pic above).

> エフェメラルデータポイントは常に左側の生サンプルに近いものを繰り返します(上の写真の赤い矢印を参照)。

VM UI でグラフの形を確認してみる

VictoriaMetrics には VM UI というクエリを投げて結果を確認できる WebUI があります。(localhost ならば http://localhost:8428/vmui/)

この画面から上記の画像で示されているようなグラフの形になるか確認してみましょう。ひな形となる URL をこちらで用意しました。

画面が表示されたら、「Trace query」にチェックを入れて、ドキュメントの画像と条件を揃えるために「Step value」の内容を 60 (秒(1分)) に変えて「EXECUTE QUERY」ボタンを押してクエリを実行してみましょう。

VictoriaMetrics VMUIでのクエリ確認画像

「Range query」の画像のようになっていることが確認できます。

VM UI を自身で触ってみたい方は、画面右上にあるデフォルトでは「LAST 30 MINUTES」となっているボタンをクリックして時刻を指定し、上記の手順 ( Step Value と Trace Query を設定) を踏むことで同様のことができます。

注意点としては利用しているブラウザのタイムゾーンを基準とするため、クエリを投げる際にはタイムゾーンが JST ならばプラス9時間としてください。

先述した curl で指定した Range Query では 2022-05-10T07:59:00.000Z ~ 2022-05-10T08:17:00.000Z なので、JST だと 2022-05-10 16:59:00 ~ 2022-05-10 17:17:00 になります。

最後に

ドキュメントの各章に関する解説は大幅にカットしましたが、この記事を通して実践的に VictoriaMetrics を試す環境が構築できたかと思います。

「こういうことをやってみると面白いよ」というネタを列挙して締めとさせていただきます。

  • 「Range query」の step=1mstep=1s に変えて、返ってくるデータの個数を jq でカウントしてみる (約 1000 と公式には記載されていますが、800 くらい)
  • VictoriaMetrics に渡すコマンドラインオプションをドキュメントを見ながら変えてみる
  • retentionPeriod をデフォルトに戻して、この記事のデータを登録してみる (おそらく、データ登録はできないはず。docker のログを合わせて見るとよいかもしれません)

この記事を通して VictoriaMetrics への理解を深める一助となれば幸いです。