Help us understand the problem. What is going on with this article?

InfluxDB インストール - 簡単な使い方

More than 5 years have passed since last update.

はじめに

システムのログや検証結果など時間に紐づく情報の入れ場所としてInfluxDBを考えていて、触ってみたのでメモしておく。

環境

  • OS: CentOS7.1
  • InfluxDB: 0.9.2

InfluxDBとは

https://influxdb.com/
Go製の時系列、メトリックス、分析用のDBでありInfluxDB外部依存はなく単体で動作するtこのこと。

主な特徴は以下とのこと

  • 時系列DB
  • SQLライクなインターフェースで解析可能
  • HTTP(s)のAPIを提供

あとはちょっと触りながら気づいたことをメモしていく。

インストール

https://influxdb.com/docs/v0.9/introduction/installation.html
にある通りにインストールしてみる。
以下のコマンドでインストール出来る。

$ wget http://influxdb.s3.amazonaws.com/influxdb-0.9.2-1.x86_64.rpm
$ sudo yum localinstall influxdb-0.9.2-1.x86_64.rpm
$ 

ansibleで書くと以下の感じ。

---
- name: be sure yum pkgs are installed    
  yum: name={{item.name}} state=present
  with_items:
    - {name: 'http://influxdb.s3.amazonaws.com/influxdb-0.9.2-1.x86_64.rpm' }

- name: be sure services are 
  service: name={{item.name }} state={{item.state}}
  with_items:
    - {name: 'influxdb', state: 'started'}

起動

systemctlで起動出来る。

$ sudo systemctl start influxdb.service

8083ポートにアクセスすると以下の画面が表示される。

CLIの使い方

https://influxdb.com/docs/v0.9/introduction/getting_started.html
を見るとinfluxというCLIがあるらしい。
以下にある。

$ sudo find / -name influx
/opt/influxdb/versions/0.9.2/influx
/opt/influxdb/influx
$

pathを通してやる。

$ sudo export PATH=/opt/influxdb/:$PATH

以下のコマンドでlocal:8086にアクセス。これが管理者用のアクセスポートらしい。

DB作成

CLI

まずDBを作成する。
MySQL系のDBと似た感じで操作することが出来そう。

$ influx
Connected to http://localhost:8086 version 0.9.2
InfluxDB shell 0.9.2

> SHOW DATABASES
name: databases
---------------
name

> CREATE DATABASE test
> SHOW DATABASES
name: databases
---------------
name
test

> 

API

以下のHTTPリクエストでも同様のことが出来そう。

curl -G http://localhost:8086/query --data-urlencode "q=CREATE DATABASE test2"
{"results":[{}]}$
$ curl -G http://localhost:8086/query --data-urlencode "q=show databases"
{"results":[{"series":[{"name":"databases","columns":["name"],"values":[["test"],["test2"]]}]}]}$

作成されている。

データ作成

CLI

Getting Startedを見る限りDBを作成すればデータを入れる準備は完了らしい。
以下のコマンドでデータを登録できる。

> USE test
Using database test
> INSERT cpu,host=serverA,region=us_west value=0.64
> SELECT * FROM cpu
name: cpu
tags: host=serverA, region=us_west
time                value
----                -----
2015-08-20T16:20:51.85486998Z   0.64

> 

SELECT文の結果を見てわかるように、INSERTの最初の項目がテーブル名で、次の空白までがメタデータ、以降が値となるよう。

以下の形式。

<measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>[,<field2-key>=<field2-value>...] [unix-nano-timestamp]

API

上記で作成したデータは以下のHTTPリクエストで作成可能。

$ curl -i -XPOST 'http://localhost:8086/write?db=test2&precision=s' --data-binary 'cpu,host=serverA,region=jp value=0.64 1440319130'

デフォルトではtimestampはnanosecondなので、integerにしたい場合はURLパラメーターにprecision=sを指定する必要がある。
timestampはオプショナルで、指定しない場合はシステム側で指定してくれる。

データを取得してみる。

$ curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=test2" --data-urlencode "q=SELECT value FROMcpu WHERE region='jp'"
{
    "results": [
        {
            "series": [
                {
                    "name": "cpu",
                    "columns": [
                        "time",
                        "value"
                    ],
                    "values": [
                        [
                            "2015-08-23T08:38:50Z",
                            0.64
                        ]
                    ]
                }
            ]
        }
    ]
}
$

複数のクエリを;で繋ぐことで一度のAPIリクエストで複数のクエリを送れるらしい。

$ curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=test2" --data-urlencode "q=SELECT value FROM cpu WHERE region='jp';SELECT value FROM cpu WHERE region='jp'"
{
    "results": [
        {
            "series": [
                {
                    "name": "cpu",
                    "columns": [
                        "time",
                        "value"
                    ],
                    "values": [
                        [
                            "2015-08-23T08:38:50Z",
                            0.64
                        ]
                    ]
                }
            ]
        },
        {
            "series": [
                {
                    "name": "cpu",
                    "columns": [
                        "time",
                        "value"
                    ],
                    "values": [
                        [
                            "2015-08-23T08:38:50Z",
                            0.64
                        ]
                    ]
                }
            ]
        }
    ]
}

resultsに複数のseriesがArray形式で格納されているよう。

クエリの書き方

時系列データなので各データは時間に紐付けられていて、時間に関するマクロが充実している。

利用データ

> SELECT * FROM cpu LIMIT 10;
name: cpu
tags: host=serverA, region=jp_east
time                value
----                -----
2015-08-26T15:27:56.173871955Z  0.68
2015-08-26T15:27:58.335904424Z  0.68
2015-08-26T15:28:00.716265129Z  0.68
2015-08-26T15:28:07.736420541Z  0.68
2015-08-26T15:28:09.956365012Z  0.68
2015-08-26T15:28:14.206256606Z  0.68
2015-08-26T15:28:16.631484237Z  0.68
2015-08-26T15:28:18.473502415Z  0.68
2015-08-26T15:28:19.435090391Z  0.68
2015-08-26T15:30:35.55368872Z   0.68

集合関数

https://influxdb.com/docs/v0.9/query_language/functions.html
^見ると以下が利用可能。

GROUP BY timeと一緒に使われることが想定されているとのこと。

  • COUNT
  • MIN
  • MAX
  • MEAN
  • MEDIAN
  • DISTINCT
  • PERCENTILE
  • DERIVATIVE
  • SUM
  • STDDEV
  • FIRST
  • LAST

以下あまり使ったことの無い関数を実行してみた。

PERCENTILE

第一引数に指定したカラムの中で、第二引数に指定した値の割合に位置するデータを返す。

> SELECT PERCENTILE(value,100) FROM cpu WHERE time > now() - 10m GROUP BY time(10s) LIMIT 5;
name: cpu
---------
time            percentile
2015-08-27T02:34:50Z    
2015-08-27T02:35:00Z    0.68
2015-08-27T02:35:10Z    0.68
2015-08-27T02:35:20Z    0.68
2015-08-27T02:35:30Z    0.68

> 

DERIVATIVE

第二引数に指定した時間の直近で、どれぐらい値が変化したかを表す関数かな。

> SELECT DERIVATIVE(value,5s) FROM cpu WHERE time > now() - 10m LIMIT 5;
name: cpu
---------
time                value
2015-08-27T02:38:23.875145931Z  0
2015-08-27T02:38:26.035984152Z  0
2015-08-27T02:38:28.195453919Z  0
2015-08-27T02:38:30.35353966Z   0

> 

MEDIAN

中央値。

> SELECT MEDIAN(value) FROM cpu WHERE time > now() - 10m GROUP BY time(10s) LIMIT 5;
name: cpu
---------
time            median
2015-08-27T02:28:50Z    
2015-08-27T02:29:00Z    0.68
2015-08-27T02:29:10Z    0.68
2015-08-27T02:29:20Z    0.68
2015-08-27T02:29:30Z    0.68

> 

STDDEV

標準偏差。
全く同じ値のデータを入れているので0となる。

> SELECT STDDEV(value) FROM cpu WHERE time > now() - 10m GROUP BY time(10s) LIMIT 5;
name: cpu
---------
time            stddev
2015-08-27T02:29:40Z    0
2015-08-27T02:29:50Z    0
2015-08-27T02:30:00Z    0
2015-08-27T02:30:10Z    0
2015-08-27T02:30:20Z    0

> 

Continuous Queries

https://influxdb.com/docs/v0.9/query_language/continuous_queries.html
を見ると、おそらく集計処理を連続的に実行してその結果を格納するためのクエリ。

以下で登録出来る。

> CREATE CONTINUOUS QUERY cpu_max_continuously ON test BEGIN SELECT MAX(value) INTO "cpu_max_continuously" FROM cpu GROUP BY time(10s) END
> SHOW CONTINUOUS QUERIES
name: test
----------
name            query
cpu_max_continuously    CREATE CONTINUOUS QUERY cpu_max_continuously ON test BEGIN SELECT max(value) INTO "test"."default".cpu_max_continuously FROM "test"."default".cpu GROUP BY time(10s) END
>
> SELECT * FROM cpu_max_continuously;
name: cpu_max_continuously
--------------------------
time            max
2015-08-27T02:56:40Z    0.68
2015-08-27T02:56:50Z    0.68
2015-08-27T02:57:00Z    0.68
2015-08-27T02:58:40Z    0.68
2015-08-27T02:58:50Z    0.68

> 

データも格納されているよう。
このデータをVisualizationツールで見せれば良さげ。

注意点

GROUP BY time

GROUP BYにtimeを指定するときはWHERE句にtimeが必要。

> SELECT mean(value) FROM cpu GROUP BY time(10s);
ERR: error parsing query: aggregate functions with GROUP BY time require a WHERE time clause
>

WHERE句のtimeは左辺に

右辺に指定すると認識されない。

> SELECT COUNT(value) FROM cpu WHERE now() > time GROUP BY time(10s);
ERR: error parsing query: aggregate functions with GROUP BY time require a WHERE time clause
> 

WHERE time && GROUP BY time の指定はある程度の個数になるように

あまり調査出来ていないが以下だとGROUP BYしても一つの行しか出力されない。

> SELECT COUNT(value) FROM cpu WHERE time < now() GROUP BY time(10s);
name: cpu
---------
time            count
1970-01-01T00:00:00Z    1264

> 

直近10分指定の場合は以下のように想定通りに出力される。

以下の出力からわかるようにデータがなくても検索結果には出力されるのでこのような作りになっているんだろうなと思う今日この頃。

> SELECT COUNT(value) FROM cpu WHERE time > now() - 10m GROUP BY time(10s);
name: cpu
---------
time            count
2015-08-27T01:49:20Z    
2015-08-27T01:49:30Z    4
2015-08-27T01:49:40Z    5
2015-08-27T01:49:50Z    5
2015-08-27T01:50:00Z    4
2015-08-27T01:50:10Z    5
2015-08-27T01:50:20Z    5
2015-08-27T01:50:30Z    4
2015-08-27T01:50:40Z    5
2015-08-27T01:50:50Z    5
2015-08-27T01:51:00Z    4
2015-08-27T01:51:10Z    5
2015-08-27T01:51:20Z    4
2015-08-27T01:51:30Z    5
2015-08-27T01:51:40Z    5
2015-08-27T01:51:50Z    4
2015-08-27T01:52:00Z    5
2015-08-27T01:52:10Z    5
2015-08-27T01:52:20Z    4
2015-08-27T01:52:30Z    5
2015-08-27T01:52:40Z    4
2015-08-27T01:52:50Z    5
2015-08-27T01:53:00Z    5
2015-08-27T01:53:10Z    4
2015-08-27T01:53:20Z    5
2015-08-27T01:53:30Z    5
2015-08-27T01:53:40Z    4
2015-08-27T01:53:50Z    5
2015-08-27T01:54:00Z    5
2015-08-27T01:54:10Z    4
2015-08-27T01:54:20Z    5
2015-08-27T01:54:30Z    4
2015-08-27T01:54:40Z    5
2015-08-27T01:54:50Z    5
2015-08-27T01:55:00Z    4
2015-08-27T01:55:10Z    5
2015-08-27T01:55:20Z    5
2015-08-27T01:55:30Z    4
2015-08-27T01:55:40Z    5
2015-08-27T01:55:50Z    5
2015-08-27T01:56:00Z    4
2015-08-27T01:56:10Z    5
2015-08-27T01:56:20Z    4
2015-08-27T01:56:30Z    5
2015-08-27T01:56:40Z    5
2015-08-27T01:56:50Z    4
2015-08-27T01:57:00Z    5
2015-08-27T01:57:10Z    5
2015-08-27T01:57:20Z    4
2015-08-27T01:57:30Z    5
2015-08-27T01:57:40Z    4
2015-08-27T01:57:50Z    5
2015-08-27T01:58:00Z    5
2015-08-27T01:58:10Z    4
2015-08-27T01:58:20Z    5
2015-08-27T01:58:30Z    5
2015-08-27T01:58:40Z    4
2015-08-27T01:58:50Z    5
2015-08-27T01:59:00Z    5
2015-08-27T01:59:10Z    4
2015-08-27T01:59:20Z    1

>

データポイント数が多すぎる場合は以下のようにエラーとなる。

> SELECT COUNT(value) FROM cpu WHERE time > now() - 100d GROUP BY time(10s);
ERR: too many points in the group by interval. maybe you forgot to specify a where time clause?
>

おわりに

ちょっと自分が使いそうなところを触って、調べきれていないところがあると思うけどそこらへんはご勘弁をmm

おしまい

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away