2017年11月6日

InfluxDB

InfluxDB是一個由 InfluxData 開發的開源時序型資料庫 Time Series Database (TSDB)。是以Go實作,提供高性能地查詢與儲存 Time Series Data。InfluxDB 可應用於儲存系統的監控資料,IoT的即時資料,類似的資料庫有Elasticsearch、Graphite。

主要特色功能

  1. 基於時間序列儲存資料,支援與時間有關的相關函數(如min, max, sum, count, mean, median 等)

  2. 以 Go 實作,編譯為一個獨立的 binary 程式,不需要其他 dependency library

  3. 提供 write and query HTTP/S API

  4. 支援 Telegraf, Graphite, collectd, OpenTSDB 的 plugin,用以取得其他資料庫的資料。

  5. InfluxQL 是 SQL-like query language,支援regular expressions, arithmetic expressions, and time series specific functions,可用在 InfluxQL 中

  6. 每秒可處理百萬個資料點,在有限時間內,提供高精確度的原始資料,舊資料就改為儲存低精確度,統計後的資料。以 Continuous Queries (CQ) and Retention Policies (RP) 支援 downsamping data 及 expiring old data

  7. InfluxDB 屬於 influxdata 的 Time Series Platform TICK 平台的一部分

    1. Telegraf: Agent of collecting and reporting metrics and events (100+ plugins)

    2. InfluxDatabase: 儲存 Time Series Data

    3. Chronograf: 包含 Dashboard 及 access control,是 InluxData Platform 的操作介面

    4. Kapacitor: Real-time streaming data processing engine

安裝

influxdata Downloads 可取得不同 OS 的安裝方式。

在 CentOS 為

wget https://dl.influxdata.com/influxdb/releases/influxdb-1.3.6.x86_64.rpm
sudo yum localinstall influxdb-1.3.6.x86_64.rpm

啟動

有兩種方式

  1. 以 service 啟動

    sudo service influxdb start
  2. 以執行檔直接啟動

    cd /usr/bin
    ./influxd

舊版的 influxdb 有包含一個 Web 管理界面 Port 是 8083,但在 1.1 版以後就被移除了,HTTP API Port 是 8086

Command Line Client

在 /usr/bin 裡面有一個 influx 執行檔,也是連接到 TCP Port 8086,進行 Database 操作。

> influx
Connected to http://localhost:8086 version 1.3.6
InfluxDB shell version: 1.3.6
  1. 查詢資料庫

    > show databases
    name: databases
    name
    ----
    _internal
  2. 建立/刪除資料庫

    > create database test
    > show databases
    name: databases
    name
    ----
    _internal
    test
    > drop database test
  3. 使用資料庫

    influxdb 的 measurements 就等同 Relational DB 的 table,不需要 create table,可直接 insert。

    查詢語法類似 SQL 指令,沒有提供修改和刪除資料的方法

    > show measurements
    > insert disk_free,hostname=server01 value=442221834240i 1435362189575692182
    > show measurements
    name: measurements
    name
    ----
    disk_free
    > select * from disk_free
    name: disk_free
    time                hostname value
    ----                -------- -----
    1435362189575692182 server01 442221834240
    
    > drop measurement disk_free

    Point 由時間(time)、標籤(tags)、數據(field)組成,代表 measurement 裡面的一個 record。

    insert 語法中,measurement 跟資料用逗號(,)隔開,tag 及 field 之間,用空格隔開,多個 tag 或多個 field 之間,用逗號(,)隔開

    在這個語法中,disk_free 為 measurement,hostname=server01 是 tag,value=442221834240i 是 field,最後面 1435362189575692182 是 Time

    insert disk_free,hostname=server01 value=442221834240i 1435362189575692182
  4. series

    series 是 measurement 裡面的數據資料,表示可以在圖表上產生幾條線,series 是通過 tags 排列組合計算出來的

    > show series from disk_free
    key
    ---
    disk_free,hostname=server01

HTTP API

### 產生 mydb database
# curl -POST http://localhost:8086/query --data-urlencode "q=CREATE DATABASE mydb"
{"results":[{"statement_id":0}]}

### 寫入一筆資料
# curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1434055562000000000'

HTTP/1.1 204 No Content
Content-Type: application/json
Request-Id: 6306518c-b54a-11e7-8023-000000000000
X-Influxdb-Version: 1.3.6
Date: Fri, 20 Oct 2017 03:54:35 GMT

### 查詢
# curl -GET 'http://localhost:8086/query?pretty=true' --data-urlencode "db=mydb" --data-urlencode "q=SELECT value FROM cpu_load_short WHERE region='us-west'"
{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "cpu_load_short",
                    "columns": [
                        "time",
                        "value"
                    ],
                    "values": [
                        [
                            "2015-06-11T20:46:02Z",
                            0.64
                        ]
                    ]
                }
            ]
        }
    ]
}


### epoch=[h,m,s,ms,u,ns] 指定輸出的時間格式
# curl -G 'http://localhost:8086/query?pretty=true' --data-urlencode "db=mydb" --data-urlencode "epoch=s" --data-urlencode "q=SELECT value FROM cpu_load_short WHERE region='us-west'"
{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "cpu_load_short",
                    "columns": [
                        "time",
                        "value"
                    ],
                    "values": [
                        [
                            1434055562,
                            0.64
                        ]
                    ]
                }
            ]
        }
    ]
}

### chunk_size 限制查詢結果的資料筆數
# curl -G 'http://localhost:8086/query' --data-urlencode "db=mydb" --data-urlencode "chunk_size=200" --data-urlencode "q=SELECT value FROM cpu_load_short WHERE region='us-west'"
{"results":[{"statement_id":0,"series":[{"name":"cpu_load_short","columns":["time","value"],"values":[["2015-06-11T20:46:02Z",0.64]]}]}]}

數據保留策略 RP (Retention Policies)

因 influxdb 可處理大量資料,如果全部都儲存下來,會佔用大量 disk 空間,可設定 Retention Policies (RP) 決定要如何保留歷史資料。

查詢 RP

> use mydb
Using database mydb
>  SHOW RETENTION POLICIES ON mydb
name    duration shardGroupDuration replicaN default
----    -------- ------------------ -------- -------
autogen 0s       168h0m0s           1        true
  1. name: 名稱
  2. duration: 持續時間,0代表無限制
  3. shardGroupDuration: shardGroup的存儲時間,shardGroup是InfluxDB的一個基本儲存結構,大於這個時間的數據在查詢效率上應該有所降低。
  4. replicaN: 全稱是REPLICATION,副本個數
  5. default: 是否是默認策略
> CREATE RETENTION POLICY "2_hours" ON "mydb" DURATION 2h REPLICATION 1 DEFAULT
> SHOW RETENTION POLICIES ON mydb
name    duration shardGroupDuration replicaN default
----    -------- ------------------ -------- -------
autogen 0s       168h0m0s           1        false
2_hours 2h0m0s   1h0m0s             1        true
> drop RETENTION POLICY "2_hours" ON "mydb"
>  SHOW RETENTION POLICIES ON mydb
name    duration shardGroupDuration replicaN default
----    -------- ------------------ -------- -------
autogen 0s       168h0m0s           1        false

連續查詢 CQ (Continuous Queries)

連續查詢主要用在將資料歸檔,以降低系統空間的佔用,主要是以降低精度為代價是。CQ 是在數據庫中自動定時啟動的一組語法,必須包含 SELECT 關鍵詞和 GROUP BY time() 關鍵詞,會將查詢結果放在指定的資料表中。

CREATE CONTINUOUS QUERY <cq_name> ON <database_name> 
[RESAMPLE [EVERY <interval>] [FOR <interval>]] 
BEGIN SELECT <function>(<stuff>)[,<function>(<stuff>)] INTO <different_measurement> 
FROM <current_measurement> [WHERE <stuff>] GROUP BY time(<interval>)[,<stuff>] 
END

測試

# curl -i -XPOST 'http://localhost:8086/write?db=mydb' --data-binary 'cpu_load_short,host=server01,region=us-west value=0.64 1508479696000000000'

# influx
Connected to http://localhost:8086 version 1.3.6
InfluxDB shell version: 1.3.6
> use mydb
Using database mydb
> select * from cpu_load_short
name: cpu_load_short
time                host     region  value
----                ----     ------  -----
1508479696000000000 server01 us-west 0.64

> CREATE RETENTION POLICY "2_hours" ON "mydb" DURATION 2h REPLICATION 1 DEFAULT
> 
> CREATE CONTINUOUS QUERY cq_30m ON mydb BEGIN SELECT mean(cpu_load_short) INTO mem_load_30m FROM mem GROUP BY time(30m) END
> 
> SHOW CONTINUOUS QUERIES
name: _internal
name query
---- -----

name: test
name query
---- -----

name: mydb
name   query
----   -----
cq_30m CREATE CONTINUOUS QUERY cq_30m ON mydb BEGIN SELECT mean(cpu_load_short) INTO mydb."2_hours".mem_load_30m FROM mydb."2_hours".mem GROUP BY time(30m) END

References

InfluxDB

InfluxDB學習系列教程

[Linux] 安裝與使用 influxDB @ Ubuntu 14.04