アルパカログ

プログラミングとマネジメントがメインです。時々エモいのも書きます。

時系列データベースInfluxDBの紹介とデータの間引きについて

最近InfluxDBを使う機会に恵まれたので「InfluxDBとは何か」を軽く紹介しつつ、使ってみて良かった点をお話ししようと思う。なお、他の時系列データベースとの比較は行なっていないので注意されたい。

f:id:otoyo0122:20190511104053p:plain:w400

InfluxDBとは

InfluxDBは時系列データベース(Time Series Database)の1つで、最初からHTTP APIを備えている(後述)という特徴がある。

RDBとは違って時系列データベースなので、例えばサーバのメトリクスやユーザーの行動ログなど、情報の1つ1つよりも、情報の変遷に意味のあるデータを保存するのに適している。サーバの監視にTSDBが用いられることは以前【読書メモ】入門監視 / 知っておこう!監視のアンチパターンでも述べた。

InfluxDBにも、定期的にデータを間引いたり(ダウンサンプリング)、古くなったデータを期限切れにしたりといった機能が備わっている(後述)。

InfluxDBを操作するためのクエリは、MySQLと似ているがMySQLのtableにあたるものをInfluxDBではmeasurementというように、用語による差異がある。違いを説明したブログはたくさん出てくるのでそちらを参照されたい。

HTTP APIが便利

一般的なRDBMSでは、PostgreSQLならPostgreSQLの、MySQLならMySQLのクライアントを使用するが、InfluxDBでは最初からHTTP APIが用意されており、デフォルトで8086版ポートにHTTPリクエストを投げつけるだけでCRUD +αのクエリができてしまうので便利だ。

docs.influxdata.com

curlコマンドなどでクエリを実行するときは、データベースを指定する db パラメータと、クエリの q パラメータが最低限あれば良い。

以下は公式より抜粋したSELECTの例だ。APIパラメータがシンプルなこと、レスポンスがJSONであることがわかる。

$ curl -G 'http://localhost:8086/query?db=mydb' --data-urlencode 'q=SELECT * FROM "mymeas"'

{"results":[{"statement_id":0,"series":[{"name":"mymeas","columns":["time","myfield","mytag1","mytag2"],"values":[["2017-03-01T00:16:18Z",33.1,null,null],["2017-03-01T00:17:18Z",12.4,"12","14"]]}]}]}

また、pretty=true を付けるとJSONを読みやすいように整形してくれる。

$ curl -G 'http://localhost:8086/query?db=mydb&pretty=true' --data-urlencode 'q=SELECT * FROM "mymeas"'

{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "mymeas",
                    "columns": [
                        "time",
                        "myfield",
                        "mytag1",
                        "mytag2"
                    ],
                    "values": [
                        [
                            "2017-03-01T00:16:18Z",
                            33.1,
                            null,
                            null
                        ],
                        [
                            "2017-03-01T00:17:18Z",
                            12.4,
                            "12",
                            "14"
                        ]
                    ]
                }
            ]
        }
    ]
}

ダウンサンプリングとデータ保持(Data Retention)

例えば30秒毎にデータを保存しているとして、そのまま1日、1週間、1年が経過するとストレージがパンクしてしまうことは容易に想像できる。

InfluxDBでは、一定期間を過ぎるとデータをまとめ、解像度を落として保持するためにContinuous Query(CQ)Retention Policy(RP)という2つ機能が備わっている。

docs.influxdata.com

CQは定期的に自動実行するクエリで、RPは保持期間を持つデータ構造だ。

使い方としては、複数の期限を設定したRPを用意しておき、CQを使ってデータの解像度ごとにRPにデータを保持しておくというイメージだ。

公式ドキュメントを参考に試してみよう。

まずDBを作成する。

CREATE DATABASE "food_data"

次にデフォルトのRPを保持期間1時間で作成する。

> CREATE RETENTION POLICY "one_hour" ON "food_data" DURATION 1h REPLICATION 1 DEFAULT

RPにはDEFAULTを設定することができ、DB内のmeasurementsのデータ保持期間はデフォルトのRPによって定められる。設定しない場合、デフォルトで無期限になっている(autogen という名前のRP)。

また、REPLICATION 1はシングルノーインスタンスのとき必須のパラメータとなっている。

デフォルトでないRPも保持期間1年(52週)で作成しておく。

> CREATE RETENTION POLICY "a_year" ON "food_data" DURATION 52w REPLICATION 1

ここで food_dataorder measurement に適当なサンプルデータを投入しておこう。

> INSERT orders,phone=10 website=30
> INSERT orders,phone=12 website=39
> INSERT orders,phone=11 website=56

> SELECT * FROM orders
name: orders
time                phone website
----                ----- -------
1557546012214138700 10    30
1557546027823595200 12    39
1557546035939292400 11    56

food_data.orders measurement を30分ごとにまとめ、RP a_yeardown_sampled_orders に保存するCQを作成する。現行のCLIツールではクエリ内の改行がサポートされていないので注意。

> CREATE CONTINUOUS QUERY "cq_30m" ON "food_data" BEGIN
  SELECT mean("website") AS "mean_website",mean("phone") AS "mean_phone"
  INTO "a_year"."downsampled_orders"
  FROM "orders"
  GROUP BY time(30m)
END

30分以上待って a_year.downsampled_orders を見ると、データがダウンサンプリングされていることがわかる。タイムスタンプのフォーマットを見やすくするために precision rfc3339 としている。

> precision rfc3339
> select * from a_year.downsampled_orders
name: downsampled_orders
time                 mean_website
----                 ------------
2019-05-11T03:30:00Z 41.666666666666664
2019-05-11T04:00:00Z 60
2019-05-11T04:30:00Z 53

また、RPの期限を過ぎたデータが削除されていることも確認できる。きっかり1時間で削除されるわけではなく、チェックのタイミングで期限切れのデータが削除される。

> SELECT * FROM one_hour.orders
name: orders
time                         phone website
----                         ----- -------
2019-05-11T04:18:35.2291329Z 13    60
2019-05-11T04:57:23.267411Z  14    53

設定したRPとCQは下記のように確認する。

> SHOW RETENTION POLICIES ON "food_data"

> SHOW CONTINUOUS QUERIES

おわりに

InfluxDBについて紹介し、中でもHTTP APIとダウンサンプリングについて取り上げた。今回はインストール方法などには触れなかったが、導入も簡単なので手段の1つとして検討いただければ幸いだ。