以前にデータを可視化する手段の一つとしてInfluxDB+Grafanaについて調べていたけれど、 その時は導入してデータ投入して動いた段階で満足してしまっていた。
そうこうしている間にバージョンは1.0を回り、ちょうど使いたい案件もあったので、 改めてもう少し真面目に使い方を調べてみた。
そもそも時系列データベースなるものは何ものなのか
もちろん時系列データが扱いやすいらしいことは名前から明らかだけど、 具体的にどう便利なのかという部分を正直なところ理解していなかった。
どこまで時系列データベース一般の話かは分からないが、 InfluxDBを実際に使ってみて「ああなるほど、こりゃ便利だ」と思ったのが
- スキーマレスなので要素の増減に柔軟に対応できる
- 時系で変化するデータを集計するのに便利な機能が揃っている
- 古いデータを自動で削除して容量を削減できる
- 時間ごとの処理を定義できる
あたりだろうか。
スキーマレス
InfluxDBはJSONの形でデータを投入する。
完全な自由形というわけではなく、
- データのタイムスタンプ
- 格納するシリーズ(RDBMSでいうテーブルみたいな概念)
- 保存したい値
- 必要に応じてタグ(僕はインディックスカラム的なものだと思ってる)
を含んだデータを挿入することになる。
(生のAPIから投げ込むならこのあたりが参考になるだろうか Querying Data with the HTTP API | InfluxData Documentation )
なのでNoSQL的に適当に放り込んでOKみたいなものではなくてある程度整形してやる必要があるが、 値やタグに関しては途中から追加することができる。
RDBMSでログ収集みたいなことをやろうとすると設計時には想定していなかったパラメータが出てきたときに頭が痛かったりするのだが、 そのあたりの悩みから開放される。
時系列での集計機能
InfluxDBはSQLライクなクエリを発行して柔軟にデータの操作が行えるのだが、 ここで時系列データを扱う際に便利なコマンドが多く用意されている。
以下のようなデータを想定する。
例えば30秒ごとの平均値の推移を得ようと思ったとき、 これがMySQLなら結構面倒なクエリを記述するか、 もしくは拾ったデータを加工するスクリプトを書く必要があるだろう。
だが、InfluxDBであれば以下のクエリで事足りる。
SELECT mean(value) FROM series WHERE time >'2016-07-03T15:00:00Z' and time < '2016-07-03T16:00:00Z' GROUP BY time(30s)
更に、空白になってしまう期間を埋める必要がある場合などはGROUP BY 30m FILL(previous)
と記述すると、
前の期間の数値で埋めてくれる。
不定期な指標を統計データとする際に非常に役に立つだろう。
データの自動削除
InfluxDBではシリーズごとにRetention Policyという機能を用いてデータに期限を持たせ、 自動的に容量を削減することができる。
例えば以下のような1日経過でデータを消すようなポリシーを作成したとする。
CREATE RETENTION POLICY "rp_daily" ON "db_name" DURATION 1d REPLICATION 1
すると、rp_daily.hogehoge
に書き込まれたデータは、タイムスタンプが1日前になったものから自動で消えることになる。
(先にシリーズをテーブルみたいなものと言ったが、正確にはポリシーとセットである。ポリシー部分を省略すると、デフォルトのポリシーのものが参照される。)
RDBMSでログ的なものを管理しようとすると、 増え続けるレコードに対して定期的に削減するようなバッチを回す(もしくは札束で容量を増して解決するか)ことになるが、 それをInfluxDB内で定義することが可能なのだ。
データの自動集計
逐次集約してきた生データを定期的に集計する、などということもサーバサイドではありがちな仕事だが、 これもInfluxDBのContinuous Queryという機能を用いることで自動でこなしてくれる。
( Continuous Queries | InfluxData Documentation )
下記のようなクエリにより定義を作成する。
CREATE CONTINUOUS QUERY "cq_summary" ON "database" BEGIN SELECT mean("value") INTO "rc_long"."summary_data" FROM "rc_short"."row_data" GROUP BY time(30m) END
先に述べたようなGROUP BYを用いた集約クエリをINTO句で指定したシリーズに挿入する。
例えば生データ側に短めのRetention Policy、集約側に長めのRetention Policyを適用することで、 「最近のデータは詳細が知りたいけど、昔のデータは大体の傾向が分かれば良い」みたいな要件に対応できる。
そんなこんなで僕自身もまだ使い始めたばかりなのだけど、 InfluxDBの便利さに驚くやら感動するやらしている今日この頃。
過去を振り返ると、今ならInfluxDBを適用すれば解決できそうな案件がいくつも思い当たる。
なかなか便利そうなプロダクトなので、個人的にはどんどん使っていってみたい。