TL;DR このエントリは InfluxDBのドキュメント懇切丁寧だけど長げーよ!と思った私が適当に必要そうな所を抜粋&補足したものです。過度な期待はしないで下さい。
時系列DB(Time Series DataBase)である
公式ドキュメント: Key Concepts
name: census
-————————————
time location scientist butterflies honeybees
2015-08-18T00:00:00Z 1 langstroth 12 23
2015-08-18T00:00:00Z 1 perpetua 1 30
2015-08-18T00:06:00Z 1 langstroth 11 28
2015-08-18T00:06:00Z 1 perpetua 3 28
2015-08-18T05:54:00Z 2 langstroth 2 11
2015-08-18T06:00:00Z 2 langstroth 1 10
2015-08-18T06:06:00Z 2 perpetua 8 23
2015-08-18T06:12:00Z 2 perpetua 7 22
上記は census(個体数調査?)という名前の measurement(測定データ=一般のRDBでいうテーブル)をCLIツールで表示したもの。時系列DBなので第一のキー項目として timeというタイムスタンプ項目が必ず設定され、オプションで追加のキー項目(InfluxDBでは tagと呼称される)として、locationとscientist(場所Noと調査科学者)が設定されている。また測定値項目(fieldと呼称される)には、butterfliesとhoneybees(蝶の個体数と蜜蜂の個体数)が設定されている。この追加のキー項目の組み合わせパターンを series(系列)として取り扱かえるなど、InfluxDBでは時系列形式のデータを効率良く管理する為の様々な仕組みが用意されている。
Dockerイメージで簡単に試してみる方法
Docker Hub: library/influxdb 公式ドキュメント: Web Admin Interface, CLI/Shell
InfluxDBのエントリ作成時の最新版は 1.4系ですが 1.3で廃止され Chronografに統合された昔の管理UIが InfluxDBだけを試すにはシンプルで分かり易いので、ここでは 1.2系を指定して使っています。
#InfluxDBサーバコンテナ作成
docker run --name=influxdb -d -p 8086:8086 -p 8083:8083 -e INFLUXDB_ADMIN_ENABLED=true influxdb:1.2
#上記コンテナに入るとCLIが使用可能
docker exec -it influxdb bash
influx -precision rfc3339
#Web管理UIにはポート8083でアクセス
<お好みのブラウザ> http://localhost:8083
#InfluxDBサーバ停止
docker stop influxdb
#InfluxDBサーバ開始
docker start influxdb
#InfluxDBサーバコンテナ削除
docker rm influxdb
基本的なデータベース管理コマンド
公式ドキュメント: Schema Exploration, Database Management
TABLEが MEASUREMENTに置き換わったぐらい、データの登録と検索の一部は特殊なので詳細は後述、後は TAGや FIELD, SERIESといった便利機能
SHOW DATABASES
CREATE DATABASE testdb
USE testdb
DROP DATABASE testdb
SHOW MEASUREMENTS
DROP MEASUREMENT tbl1
SELECT * FROM tbl1
INSERT tbl1,tag1='a' fld1=1
DELETE * FROM tbl1
SHOW TAG KEYS FROM tbl1
SHOW TAG VALUES FROM tbl1 WITH KEY = tag1
SHOW FIELD KEYS FROM tbl1
SHOW SERIES FROM tbl1
DROP SERIES FROM tbl1 WHERE tag1 = 'a'
※バージョン 1.3から -- や /* */ の SQLコメントが使えるようだが 1.2では使えない模様
時系列データの登録方法
公式ドキュメント: Line Protocol Tutorial, Line Protocol Reference, Writing Data with the HTTP API
Lineプロトコルと呼ばれている 1行1レコードの専用形式をWeb管理UIなら複数行まとめて、CLIなら前にINSERTを付加して1行づつ登録できる。また measurementへは事前に項目形式を設定せずに登録可能で、後から項目を追加する事にも制限が無い。この形式を採用している理由については調べてみたが見当たらずで、本来の利用としては監視エージェントや計測機器からHTTP APIでデータ登録する為のものなので、その際に登録し易い形式を採用したのではと推測している。
weather,location=us-midwest temperature=82 1465839830100400200
| -------------------- -------------- |
| | | |
| | | |
+-----------+--------+-+---------+-+---------+
|measurement|,tag_set| |field_set| |timestamp|
+-----------+--------+-+---------+-+---------+
INSERT weather,location=us-midwest temperature=50
SELECT * INTO weather_copy FROM weather
その他、SELECT文のINTO句で measurementを指定する事により、クエリ結果をコピーしたりする事も可能
時系列データをクエリ検索
公式ドキュメント: Data Exploration, Sample Data
SELECT文は一般的な構文はだいたい使用可能で(おっと JOINは使えません)時系列のGROUP BYでは拡張構文で時間間隔、開始オフセット、時間間隔内にデータが存在しなかった場合に何をセットするか(ヌル、数値指定、線形補完、ポイント無し、前データ値)などが指定できちゃいます。
SELECT <function>(<field_key>)
FROM_clause
WHERE <time_range>
GROUP BY time(<time_interval>,<offset_interval>),[tag_key] [fill(<fill_option: null/numeric/linear/none/previous>)]
SELECT MAX(water_level)
FROM h2o_feet
WHERE time >= '2015-09-18T16:00:00Z' AND time <= '2015-09-18T16:42:00Z'
GROUP BY time(12m,3m),location fill(0)
GROUP BYで * を指定すると設定されているタグ項目全てが指定された事となり、LIMIT/OFFSETと同様の指定で SLIMIT/SOFFSETでシリーズの表示数、開始オフセットが指定可能
SELECT water_level FROM h2o_feet GROUP BY * SLIMIT 1 SOFFSET 1
時間指定のタイムゾーン設定や時間計算の指定はわりと柔軟に書けたりもする
SELECT water_level FROM h2o_feet
WHERE time >= '2015-08-18T00:00:00Z' - 5m AND time <= '2015-08-18T00:00:00Z' + 5m tz('America/Chicago')
SQL文の結構な部分で正規表現が使えるようになってて、まあ便利といえば便利
SELECT * FROM /.*/ LIMIT 1
検索クエリで使える組み込み関数
公式ドキュメント: Functions
-
集計関数は COUNT(), DISTINCT(), SUM() の他に
- INTEGRAL()
- MEAN()
- MEDIAN()
- MODE()
- SPREAD()
- STDDEV()
-
選択関数は MIN(), MAX() の他に
- FIRST()
- LAST()
- TOP()
- BOTTOM()
- PERCENTILE()
- SAMPLE()
-
変換関数として
- CUMULATIVE_SUM()
- DERIVATIVE()
- DIFFERENCE()
- ELAPSED()
- MOVING_AVERAGE()
- NON_NEGATIVE_DERIVATIVE()
- NON_NEGATIVE_DIFFERENCE()
-
予測関数として
- HOLT_WINTERS()
ダウンサンプリング&データリテンション
公式ドキュメント: Downsampling and Data Retention
InfluxDBには RETENTION POLICYと呼ばれるデータ保持期間を設定する機能と CONTINUOUS QUERYと呼ばれる定期的にクエリを実行する機能があり、それらを使って高精度のデータは直近の期間のみ保持、集約して量を減らしたデータは長期保存して置くなどの設定が非常に簡単に行えます。
SHOW RETENTION POLICIES
-- 2時間のRPを作成、デフォルトに設定
CREATE RETENTION POLICY two_hours ON food_data DURATION 2h REPLICATION 1 DEFAULT
-- 52週のRPを作成
CREATE RETENTION POLICY a_year ON food_data DURATION 52w REPLICATION 1
-- 30分間隔にダウンサンプルしたデータを52週のRPのデータとして追加するCQ
-- 実行間隔はGROUP BY time()の間隔が自動で設定される、新データの集計が必要なタイミング
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
DROP RETENTION POLICY autogen ON food_data
SHOW CONTINUOUS QUERIES
一般的なSQLとの違い
公式ドキュメント: Comparison to SQL
最初に記述した通り timeという時系列を表す専用で必須のフィールドがあるのと、細かな用語の違い。またフィールド定義を行わず、後から自由に項目追加、必須項目の指定も無いスキーマレスなデータ定義。時系列データの保存と分析に特化した機能が追加。CRUDでは無く CR-udでデータの追加と参照は得意だが、更新と削除については不得手
ユーザ認証とアクセス制御
公式ドキュメント: Authentication and Authorization
デフォルト設定でユーザ認証はOFFになっているが、InfluxDB設定ファイルの auth-enabled設定を有効にすれば、ユーザ認証が通った接続のみ許可される様になる
[http]
auth-enabled = true
ユーザ管理とアクセス制御のコマンドは以下、ALL PRIVILEGES権限を付けると管理者ユーザとなり全ての操作が可能となる
SHOW USERS
CREATE USER admin WITH PASSWORD '***' WITH ALL PRIVILEGES
GRANT ALL PRIVILEGES TO admin
REVOKE ALL PRIVILEGES FROM admin
CREATE USER user1 WITH PASSWORD '***'
GRANT [READ,WRITE,ALL] ON testdb TO user1
REVOKE [READ,WRITE,ALL] ON testdb TO user1
SHOW GRANTS FOR user1
SET PASSWORD FOR user1 = '***'
DROP USER user1
HTTPS設定、API仕様、ライブラリ、活用法
公式ドキュメント: HTTPS Setup, API Reference, API Client Libraries
HTTPS設定については InfluxDB設定ファイルの https-enabled設定を有効にして、サーバ証明書ファイルと鍵ファイルを指定すれば設定完了
[http]
https-enabled = true
https-certificate = "server.crt"
https-private-key = "server.key"
InfluxDBに計測したデータを集積していく方法として、自前のアプリケーションから APIを呼んだり、ライブラリを使う事が出来るというのは知っておいても悪くは無いが、InfluxDBを開発している InfluxData社がTelegrafという非常に高機能かつ柔軟に設定が可能なデータ収集エージェントを提供しているので、まずはそちらが使えないを見てみた方が良いと思われる。そして時系列データの変化検知、可視化等を含んださらなる拡張システムとして InfluxDB, Telegrafを主要コンポーネントとした TICK Stack というプラットフォームもあるので、そちらを使ってみたりするのも超おススメDEATH!