InfluxDBについて最初に知るべき10のこと


TL;DR このエントリは InfluxDBのドキュメント懇切丁寧だけど長げーよ！と思った私が適当に必要そうな所を抜粋&補足したものです。過度な期待はしないで下さい。

# 時系列DB(Time Series DataBase)である
公式ドキュメント: [Key Concepts](https://docs.influxdata.com/influxdb/v1.3/concepts/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](https://hub.docker.com/_/influxdb/) 公式ドキュメント: [Web Admin Interface](https://docs.influxdata.com/chronograf/v1.3/guides/transition-web-admin-interface/), [CLI/Shell](https://docs.influxdata.com/influxdb/v1.3/tools/shell/)

InfluxDBのエントリ作成時の最新版は 1.4系ですが [1.3で廃止され Chronografに統合された昔の管理UI](https://docs.influxdata.com/influxdb/v1.3/administration/differences/#web-admin-ui-removal)が 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](https://docs.influxdata.com/influxdb/v1.3/query_language/schema_exploration/), [Database Management](https://docs.influxdata.com/influxdb/v1.3/query_language/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](https://docs.influxdata.com/influxdb/v1.3/write_protocols/line_protocol_tutorial/), [Line Protocol Reference](https://docs.influxdata.com/influxdb/v1.3/write_protocols/line_protocol_reference/), [Writing Data with the HTTP API](https://docs.influxdata.com/influxdb/v1.3/guides/writing_data/)
Lineプロトコルと呼ばれている 1行1レコードの専用形式を[Web管理UIなら複数行まとめて](https://docs.influxdata.com/chronograf/v1.3/guides/transition-web-admin-interface/#writing-data)、[CLIなら前にINSERTを付加して1行づつ](https://docs.influxdata.com/influxdb/v1.3/tools/shell/#write-data-to-influxdb-with-insert)登録できる。また measurementへは事前に項目形式を設定せずに登録可能で、後から項目を追加する事にも制限が無い。この形式を採用している理由については調べてみたが見当たらずで、本来の利用としては監視エージェントや計測機器から[HTTP APIでデータ登録](https://docs.influxdata.com/influxdb/v1.3/guides/writing_data/)する為のものなので、その際に登録し易い形式を採用したのではと推測している。

```
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句](https://docs.influxdata.com/influxdb/v1.3/query_language/data_exploration/#the-into-clause)で measurementを指定する事により、クエリ結果をコピーしたりする事も可能

# 時系列データをクエリ検索
公式ドキュメント: [Data Exploration](https://docs.influxdata.com/influxdb/v1.3/query_language/data_exploration/), [Sample Data](https://docs.influxdata.com/influxdb/v1.3/query_language/data_download/)
SELECT文は一般的な構文はだいたい使用可能で（おっと JOINは使えません）時系列のGROUP BYでは[拡張構文](https://docs.influxdata.com/influxdb/v1.3/query_language/data_exploration/#advanced-group-by-time-syntax)で時間間隔、開始オフセット、時間間隔内にデータが存在しなかった場合に何をセットするか（ヌル、数値指定、線形補完、ポイント無し、前データ値）などが指定できちゃいます。

```
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](https://docs.influxdata.com/influxdb/v1.3/query_language/data_exploration/#the-slimit-clause)/[SOFFSET](https://docs.influxdata.com/influxdb/v1.3/query_language/data_exploration/#the-soffset-clause)でシリーズの表示数、開始オフセットが指定可能

```
SELECT water_level FROM h2o_feet GROUP BY * SLIMIT 1 SOFFSET 1
```

[時間指定のタイムゾーン設定](https://docs.influxdata.com/influxdb/v1.3/query_language/data_exploration/#the-time-zone-clause)や[時間計算の指定](https://docs.influxdata.com/influxdb/v1.3/query_language/data_exploration/#time-syntax)はわりと柔軟に書けたりもする

```
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文の結構な部分で[正規表現](https://docs.influxdata.com/influxdb/v1.3/query_language/data_exploration/#regular-expressions)が使えるようになってて、まあ便利といえば便利

```
 SELECT * FROM /.*/ LIMIT 1
```

# 検索クエリで使える組み込み関数
公式ドキュメント: [Functions](https://docs.influxdata.com/influxdb/v1.3/query_language/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](https://docs.influxdata.com/influxdb/v1.3/guides/downsampling_and_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](https://docs.influxdata.com/influxdb/v1.3/concepts/crosswalk/)
最初に記述した通り timeという時系列を表す専用で必須のフィールドがあるのと、細かな用語の違い。またフィールド定義を行わず、後から自由に項目追加、必須項目の指定も無いスキーマレスなデータ定義。時系列データの保存と分析に特化した機能が追加。CRUDでは無く CR-udでデータの追加と参照は得意だが、更新と削除については不得手

# ユーザ認証とアクセス制御
公式ドキュメント: [Authentication and Authorization](https://docs.influxdata.com/influxdb/v1.3/query_language/authentication_and_authorization/)
デフォルト設定でユーザ認証はOFFになっているが、InfluxDB設定ファイルの auth-enabled設定を有効にすれば、ユーザ認証が通った接続のみ許可される様になる

```/etc/influxdb/influxdb.conf
[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](https://docs.influxdata.com/influxdb/v1.3/administration/https_setup/), [API Reference](https://docs.influxdata.com/influxdb/v1.3/tools/api/), [API Client Libraries](https://docs.influxdata.com/influxdb/v1.3/tools/api_client_libraries/)
HTTPS設定については InfluxDB設定ファイルの https-enabled設定を有効にして、サーバ証明書ファイルと鍵ファイルを指定すれば設定完了

```/etc/influxdb/influxdb.conf
[http]  
  https-enabled = true
  https-certificate = "server.crt"
  https-private-key = "server.key"
```

InfluxDBに計測したデータを集積していく方法として、自前のアプリケーションから [APIを呼んだり](https://docs.influxdata.com/influxdb/v1.3/tools/api/)、[ライブラリを使う](https://docs.influxdata.com/influxdb/v1.3/tools/api_client_libraries/)事が出来るというのは知っておいても悪くは無いが、InfluxDBを開発している [InfluxData](https://www.influxdata.com/)社が[Telegraf](https://github.com/influxdata/telegraf)という非常に高機能かつ柔軟に設定が可能なデータ収集エージェントを提供しているので、まずはそちらが使えないを見てみた方が良いと思われる。そして時系列データの変化検知、可視化等を含んださらなる拡張システムとして InfluxDB, Telegrafを主要コンポーネントとした [TICK Stack](https://www.influxdata.com/time-series-platform/) というプラットフォームもあるので、そちらを使ってみたりするのも[超おススメDEATH！](https://nmrmsys.github.io/slides/TICK-Stack-Loooooosely-ServerMonitoring-by-TimeSeriesDB.html)

# 参考文献
- [InfluxDB Version 1.3 Documentation](https://docs.influxdata.com/influxdb/v1.3/)
- [InfluxDBについて調べたこと](https://qiita.com/T0000N/items/ea5944a9a1650a59fa90)
- [InfluxDBきほんのき](https://qiita.com/iyunoriue/items/1fcbc7c7fb9e6912816c)
- [InfluxDB インストール - 簡単な使い方](https://qiita.com/akito1986/items/9c1c14a36654646db456)
- [TICK stack でモニタリング環境を構築 (Telegraf + InfluxDB + Chronograf + Kapacitor)](https://qiita.com/quickguard/items/31e8d5ced9be54c25a8c)
- [時系列DB・可視化のいまむかし](https://qiita.com/_____/items/10edb83e6d6db25ef02c)
- [influxDBとGrafanaで手の届かないところ](https://qiita.com/chroju/items/d3f145e173faec3ddc77)