InfluxDB入門

# InfluxDBとは
- TICKスタックの一部である時系列データベースの実装
- single binaryで軽い実装であることが特徴。GO（Googleが開発したプログラミング言語）で書かれている



# 時系列データ（Time Series Data）とは
CPU使用率や温度などのセンサデータや、株価のような時系列で変わっていく多数のデータの管理に特化したデータベース

- 時刻をインデックスに持ったデータの集まり
- 折れ線グラフとして可視化されることが多い
- 特定の時刻のデータは1つである
- データは同じ時間間隔で並んでいる必要がある
    - CPUモニタリングのようなデータは最初からデータが等間隔に並ぶ  
    - Webのクリックイベントのようなデータはそのままでは等間隔に並ばない → 集約が必要



# TICKスタックとは
InfluxDBを含む、OSSのデータ解析基盤。

- **Telegraf**  
NWやアプリなど、各種システムからデータを収集するエージェント（デーモン）。プラグインで様々なデータソースからのInput、様々なデータストアへのoutputに対応可能  
- **InfluxDB**
- **Chronograf**  
データを可視化するためのGUI・ダッシュボードを提供するアプリ。データにアクセスするユーザの管理も行う  
Grapanaとの違いはTICKスタックの一部であるため、InfluxDBでの利用に特化していること。Grafanaは他のデータソースにも幅広く対応できる。
- **Kapacitor**  
InfluxDBのデータを解析し、オペレータにアラームを送るなどのアクションを行うためのツール。リアルタイムデータの処理とバッチ処理の両方が可能。プラグインで機能追加でき、機械学習等のAI的処理も実現可能。

# 用語
- **DB**  
一般的なリレーショナルデータベースと同じで、データ群を保持する1つの箱の単位
- **メジャーメント**  
リレーショナルDBのテーブルに相当するもの。タグ、フィールド、タイムスタンプをカラムに持つ二次元の表をイメージするとよい。メジャーメントにはユーザが文字列の名前をつけることができる
- **タグ**  
フィールドに付与するメタデータ。`key=value`で表現される。この場合`value`は文字列。タグは複数付与することができる。データの検索はタグでフィルタすることで高速化されるため、複数の有効なタグを持つことは重要
- **フィールド**  
`key=value`で表される実際のデータ。値は整数・浮動小数点数・文字列・真偽値、のいずれかとなる。
- **タイムスタンプ**  
時刻情報。InfluxDBは時系列DBなので1つ1つのメジャーメントに必ずタイムスタンプが必要。タイムスタンプはエポックタイム（UNIX秒。1970年1月1日0時0分0秒を起点とする秒数)で表現される
- **シリーズ**  
RP、メジャーメント、タグセットが同一のデータ群。つまり特定の地点の特定のセンサデータのような、時系列に集めることで意味を成すデータ。
- **リテンションポリシー（RP）**  
InfluxDBがどの程度の期間データを保持するか（DURATION）を規定するもの。またデータのコピーをいくつ保持するか（REPLICATION）も規定する。



# InfluxQL
Influx Query Language。InfluxDBのSQLライクなクエリ言語。

- **show databases**：DBの一覧を表示。
- **use <db_name>**：利用するDBを指定
- **SELECT \<field_key> FROM \<measurement_name>**：データを抽出  
etc.


### SELECT
- **特定フィールド、タグの出力**  
`SELECT time,<field> FROM <measurement>`  
`SELECT *::field FROM <measurement>`
- **出力数の制限**  
`SELECT * FROM <measurement> LIMIT <n>`
- **フィールド値のmodify**  
`SELECT <field>/1000 FROM <measurement>`
- **複数のメジャーメントからの出力**  
`SELECT * FROM <measurement1>,<measurement2>` 

※メジャーメント・フィールド・タグの名前はそれぞれダブルクォーテーションで囲むのがよいようだ

### WHERE
条件文。

```sql

> SELECT * FROM <measurement> WHERE <key> <condition>
> SELECT * FROM cpu WHERE value > 80
> SELECT * FROM cpu WHERE "location" = 'tokyo'
※tagやfieldの値が文字列のときはダブルクウォートでなくてシングルクウォートで囲む
> SELECT * FROM cpu WHERE "location" = 'tokyo' AND value > 80
> SELECT * FROM cpu WHERE time > now( ) - 3d    //直近3日間
```

### GROUP BY
データをグループ化して表示する。

```sql
> SELECT * FROM <measurement> GROUP BY <tag>
> SELECT MEAN("value") FROM cpu GROUP BY time(12m)

> select count("available") from memory_mb where time > now() - 3d  group by time(1d)
name: memory_mb
time                count
----                -----
1558224000000000000 0
1558310400000000000 0
1558396800000000000 0
1558483200000000000 468

```

※GROUP BYでtimeを指定する場合、その前にWHEREで参照するデータの範囲を時間で指定する。

### INTO
DBから抽出したデータをもとに新しいDBを作成する
データのダウンサンプリング（複数のデータを例えば10分単位などでマージしてデータ量を減らすこと）などに利用する
指定がなければタグはコピーされずに抽出したフィールドのみがコピーされる（？）

### サブクエリ
クエリの中にネスト（入れ子になった）クエリ

# API
InfluxDBのデータの参照はHTTP/HTTPSでのAPI経由でも実施可能。  
rubyやpythonのInfluxDBライブラリはこのAPIのラッパー。
### チャンクサイズ
API経由でのクエリに応答するときに、一度に返すエントリの最大値

# Retention Policy
データをどの程度の期間保持するか、などを定義する 
１つのDBは複数のRPを持つことができる。またRPはDBごとにユニークである。

```
> CREATE RETENTION POLICY <policyname> ON <dbname> DURATION <データを保持する時間> REPLICATION <コピーを保持する数>
> ALTER RETENTION POLICY <policyname> ON <dbname> DURATION <データを保持する時間> REPLICATION <コピーを保持する数> DEFAULT #policyの修正。最後のDEFAULTはこのポリシーをデフォルトにするの意
> DROP RETENTION POLCY <policyname> ON <dbname> #policyの削除

```

#Continuous Query
指定したインターバル時間ごとに自動的に実行されるクエリ。  
あるDBからDownsampleした別のDBを自動的に作る、といった用途に利用。  
インターバル時間内に生成された新しいデータが自動的にクエリの対象となる。

## offset
`GROUP BY time(1h,15m)` 
## FOR
## fill



# Tips 
### メジャーメント名とタグ
出所が違うが似たような形式の複数のデータシリーズを管理するとき、メジャーメント名を分けて管理するという方法が考えられるが、これは悪手である。メジャーメント名には例えば「CPU使用率」といったデータの種類を示す言葉を使い、その出所などデータを分類する項目は全てタグとするのがよい。  
メジャーメント名で分類すると、グラフ化するときにとても不便になるし、そもそも1つのDB中のメジャーメント数は10程度に収めるのが望ましい。

### タグの付け方
- 1つのタグは1つの属性のみを表現すること。例えばセンサの設置場所と種類のような属性は、それぞれ別のタグとすること。`tokyo_temperature`と`osaka_humidity`のように2つの属性を1つのタグで表さないこと。
- フィールド名と同じタグ名を使わないこと。


# 認証・認可
InfluxDBはデフォルトではユーザ認証は行わない（ポート番号さえわかれば自由にアクセスできる）。
### 認証
- ユーザの作成

```sql
> CREATE USER <username> WITH PASSWORD <password> WITH ALL PRIVILEGES  #管理者権限でユーザを作成
```

- 認証の有効化 
 
以下変更してDaemonを再起動

```conf
[http]
  auth-enabled = true  #false->trueにする
```

- 認証してログイン
```
> influx -username <username> -password <password>
```
または環境変数を書く

```bash_profile.sh
INFLUX_USERNAME=<username>
INFLUX_PASSWORD=<password>
```

HTTPでは3つのオプションがある。
1. Basic認証
2. クエリパラメータで認証情報を指定
3. bodyで認証情報を指定

### 認可

- DBとユーザの組み合わせ毎にREAD,WRITE,ALL（READ+WRITE）を指定

```sql
> GRANT READ ON <dbname> TO <username>
> REVOKE ALL ON <dbname> TO <username> #権限を削除

> SHOW GRANTS FOR <username> #ユーザの権限を確認
```