Fork me on GitHub
Fork me on GitHub

时序数据库InfluxDB

最近帮助公司前端小伙伴处理他们的nginx访问日志,log的数据是半结构化的数据,同时也是典型的时序数据,每一条数据都带有时间戳。于是考虑使用时间序列数据库存储,而不会去使用mysql或是mongodb(zabbix用的是mysql,它在IO上面遇到了瓶颈)。现在时间序列的数据库是有很多的,比如graphite、opentsdb以及新生的influxdb。这次我使用了InfluxDB,在此记录下学习过程,同时也希望能够帮助到其他学习的同学。

InfluxDB介绍

什么是时间序列数据?最简单的定义就是数据格式里包含timestamp字段的数据。比如股票市场的价格,环境中的温度,主机的CPU使用率等。但是又有什么数据是不包含timestamp的呢?几乎所有的数据都可以打上一个timestamp字段。时间序列数据更重要的一个属性是如何去查询它。在查询的时候,对于时间序列我们总是会带上一个时间范围去过滤数据。同时查询的结果里也总是会包含timestamp字段。
InfluxDB 是一个开源分布式时序、事件和指标数据库。使用 Go 语言编写,无需外部依赖。其设计目标是实现分布式和水平伸缩扩展。
它有三大特性:

  1. Time Series (时间序列):你可以使用与时间有关的相关函数(如最大,最小,求和等)
  2. Metrics(度量):你可以实时对大量数据进行计算
  3. Eevents(事件):它支持任意的事件数据
    特点:
  • schemaless(无结构),可以是任意数量的列
  • min, max, sum, count, mean, median 一系列函数,方便统计
  • Native HTTP API, 内置http支持,使用http读写
  • Powerful Query Language 类似sql
  • Built-in Explorer 自带web管理界面。(从1.4版本开始去除了自带的web管理界面)

安装部署InfluxDB

influxdb下载地址:
https://portal.influxdata.com/downloads
influxdb文档:
http://docs.influxdata.com/influxdb/v1.4/introduction/getting_started/

1.下载安装
对于在不同操作系统上安装,官网都有说明,我这里使用的是CentOS 7。



[root@docdesginer local]# wget https://dl.influxdata.com/influxdb/releases/influxdb-1.4.2.x86_64.rpm
[root@docdesginer local]# yum localinstall influxdb-1.4.2.x86_64.rpm
[root@docdesginer local]# rpm -ql influxdb
/etc/influxdb/influxdb.conf
/etc/logrotate.d/influxdb
/usr/bin/influx
/usr/bin/influx_inspect
/usr/bin/influx_stress
/usr/bin/influx_tsm
/usr/bin/influxd
/usr/lib/influxdb/scripts/influxdb.service
/usr/lib/influxdb/scripts/init.sh
/usr/share/man/man1/influx.1.gz
/usr/share/man/man1/influx_inspect.1.gz
/usr/share/man/man1/influx_stress.1.gz
/usr/share/man/man1/influx_tsm.1.gz
/usr/share/man/man1/influxd-backup.1.gz
/usr/share/man/man1/influxd-config.1.gz
/usr/share/man/man1/influxd-restore.1.gz
/usr/share/man/man1/influxd-run.1.gz
/usr/share/man/man1/influxd-version.1.gz
/usr/share/man/man1/influxd.1.gz
/var/lib/influxdb
/var/log/influxdb

2.启动

[root@docdesginer local]# systemctl start influxdb 
[root@docdesginer local]# systemctl status influxdb

3.登录
客户端工具:

[root@docdesginer local]# /usr/bin/influx
Connected to http://localhost:8086 version 1.4.2
InfluxDB shell version: 1.4.2
> 

查看数据库:

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

HTTP API访问:

[root@docdesginer ~]# curl -G http://localhost:8086/query --data-urlencode "q=SHOW DATABASES"
{"results":[{"statement_id":0,"series":[{"name":"databases","columns":["name"],"values":[["_internal"]]}]}

此时数据库中还有没有用户,还没开启认证。

开启认证

1.创建管理员

[root@docdesginer local]# /usr/bin/influx
Connected to http://localhost:8086 version 1.4.2
InfluxDB shell version: 1.4.2
> CREATE USER root WITH PASSWORD 'wisedu123' WITH ALL PRIVILEGES
> quit

2.修改配置文件,开启认证
By default, authentication is disabled in the configuration file. Enable authentication by setting the auth-enabled option to true in the [http] section of the configuration file:

[http]  
  enabled = true  
  bind-address = ":8086"  
  auth-enabled = true 
  log-enabled = true  
  write-tracing = false  
  pprof-enabled = false  
  https-enabled = false  
  https-certificate = "/etc/ssl/influxdb.pem" 

重启InfluxDB:

[root@docdesginer ~]# systemctl restart influxdb 

3.再次登录
客户端工具连接数据库:

[root@docdesginer ~]# influx
Connected to http://localhost:8086 version 1.4.2
InfluxDB shell version: 1.4.2
> show databases;
ERR: unable to parse authentication credentials
Warning: It is possible this error is due to not setting a database.
Please set a database with the command "use <database>".
>

[root@docdesginer ~]# /usr/bin/influx
Connected to http://localhost:8086 version 1.4.2
InfluxDB shell version: 1.4.2
> auth
username: root
password: 
> show databases;
name: databases
name
----
_internal
> 
或者
[root@docdesginer ~]# /usr/bin/influx -username root -password wisedu123 -precision rfc3339 
Connected to http://localhost:8086 version 1.4.2
InfluxDB shell version: 1.4.2
> show databases;
name: databases
name
----
_internal
> 

HTTP API:

[root@docdesginer ~]# curl -G http://localhost:8086/query --data-urlencode "q=SHOW DATABASES"                  
{"error":"unable to parse authentication credentials"}
[root@docdesginer ~]# curl -G http://localhost:8086/query -u root:wisedu123 --data-urlencode "q=SHOW DATABASES"
{"results":[{"statement_id":0,"series":[{"name":"databases","columns":["name"],"values":[["_internal"]]}]}

InfluxDB概念

1.influxdb相关名词(可类比关系型数据库)

  • database:数据库。
  • measurement:数据库中的表。它就是tag,field,time的容器;对于influxDB的measurement来说,field是必须的,并且不能根据field来排序;Tag是可选的,tag可以用来做索引,tag是以字符串的形式存放的。
  • points:表里面的一行数据。

2.influxDB中独有的概念
(1)Point由时间戳(time)、数据(field)和标签(tags)组成。

  • time:每条数据记录的时间,也是数据库自动生成的主索引;
  • fields:各种记录的值;
  • tags:各种有索引的属性。

InfluxDb不需要做schema定义,这意味着你可以随意的添加measurements, tags, and fields at any time。

(2)series
a series is the collection of data that share a retention policy, measurement, and tag set
所有在数据库中的数据,都需要通过图表来展示,而这个series表示这个表里面的数据,可以在图表上画成几条线:通过tags排列组合算出来。
其实一个series就是一个测点,或者说一条曲线,那么retention policy, measurement, tagset就共同组成了一个定位测点序列的唯一标识。
point,就是某个series的同一个时刻的多个field的value,就组成了一个point;其实就是一条曲线上的一个点。

(3)retention policy
保留策略,用于决定要保留多久的数据,保存几个备份,以及集群的策略等。

InfluxDB基本操作

连接数据库:

[root@docdesginer ~]# /usr/bin/influx -username root -password wisedu123 -precision rfc3339   
Connected to http://localhost:8086 version 1.4.2
InfluxDB shell version: 1.4.2
> 

这里的-precision参数指定了时间戳的格式为rfc3339,也可以不使用该参数。
查看数据库:

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

创建数据库:

> CREATE DATABASE mydb
> SHOW DATABASES
name: databases
name
----
_internal
mydb
>

进入数据库:

> USE mydb
Using database mydb
>

插入数据:
influxDB存储数据采用的是Line Protocol格式。
Line Protocol格式:写入数据库的Point的固定格式。格式如下:

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

比如:

weather,location=us-midwest temperature=82 1465839830100400200
  |    -------------------- --------------  |
  |             |             |             |
  |             |             |             |
+-----------+--------+-+---------+-+---------+
|measurement|,tag_set| |field_set| |timestamp|
+-----------+--------+-+---------+-+---------+

【注意】:最后的timestamp是 unix时间戳*1000000000 的值,或者使用 %Y-%m-%dT%H:%M:%SZ 这种格式。使用其他格式在插入时会报错。

示例:

> INSERT cpu,host=serverA,region=us_west value=0.64

其中:

  • cpu是表名
  • host=serverA,region=us_west 是tag
  • value=0.64是field

想对此格式有详细的了解参见官方文档

查询数据:
influxDB是支持类sql语句的,具体的查询语法都差不多。

> select * from cpu
name: cpu
time                           host    region  value
----                           ----    ------  -----
2017-12-15T13:17:09.660446488Z serverA us_west 0.64

【注意】:InfluxDB集群功能已经不再开源。要想使用集群服务需要购买企业版。开源版和企业版的主要区别就是企业版的InfluxDB支持集群,而开源版不支持,此外企业版提供了先进的备份/恢复功能,而开源版本没有。但InfluxDB单机版性能也足够支撑中小公司的业务了。

InfluxDB数据保存策略(Retention Policies)

InfluxDB每秒可以处理成千上万条数据,要将这些数据全部保存下来会占用大量的存储空间,有时我们可能并不需要将所有历史数据进行存储,因此,InfluxDB推出了数据保留策略(Retention Policies),用来让我们自定义数据的保留时间。
InfluxDB的数据保留策略(RP) 用来定义数据在InfluxDB中存放的时间,或者定义保存某个期间的数据。
一个数据库可以有多个保留策略,但每个策略必须是独一无二的。

1.查询策略
可以通过如下语句查看数据库的现有策略:

> SHOW RETENTION POLICIES ON mydb
name    duration shardGroupDuration replicaN default
----    -------- ------------------ -------- -------
autogen 0s       168h0m0s           1        true
> 

【说明】:数据库mydb只有一个策略,各字段的含义如下:

  • name:名称,此示例名称为 autogen。当你创建一个数据库的时候,InfluxDB会自动为数据库创建一个名叫 autogen 的策略,这个策略会永久保存数据。你可以重命名这个策略,并且在InfluxDB的配置文件中禁止掉自动创建策略。
  • duration:数据保存时间,0代表无限制
  • shardGroupDuration:shardGroup的存储时间,shardGroup是InfluxDB的一个基本储存结构。
  • replicaN:全称是REPLICATION,副本个数
  • default:是否是默认策略。

这里有两个概念:
shard:
shard 在 InfluxDB 中是一个比较重要的概念,它和 retention policy 相关联。每一个存储策略下会存在许多 shard,每一个 shard 存储一个指定时间段内的数据,并且不重复,例如 7点-8点 的数据落入 shard0 中,8点-9点的数据则落入 shard1 中。每一个 shard 都对应一个底层的 tsm 存储引擎,有独立的 cache、wal、tsm file。
创建数据库时会自动创建一个默认存储策略,永久保存数据,对应的在此存储策略下的 shard 所保存的数据的时间段为 7 天,也就是上面查询时看到的168h。计算的函数如下:

func shardGroupDuration(d time.Duration) time.Duration {
    if d >= 180*24*time.Hour || d == 0 { // 6 months or 0
        return 7 * 24 * time.Hour
    } else if d >= 2*24*time.Hour { // 2 days
        return 1 * 24 * time.Hour
    }
    return 1 * time.Hour
}

如果创建一个新的 retention policy 设置数据的保留时间为 1 天,则单个 shard 所存储数据的时间间隔为 1 小时,超过1个小时的数据会被存放到下一个 shard 中。

shard group:
shard group是shards的逻辑容器。

2.创建策略
语法:

CREATE RETENTION POLICY <retention_policy_name> ON <database_name> DURATION <duration> REPLICATION <n> [SHARD DURATION <duration>] [DEFAULT]

其中:SHARD DURATION子句决定了每个shard group存储的时间间隔,在永久存储的策略里这个子句是无效的。这个子句是可选的。shard group duration默认由策略的 duration 决定。

Retention Policy’s DURATION Shard Group Duration
< 2 days 1 hour
>= 2 days and <= 6 months 1 day
> 6 months 7 days

示例1:为数据库mydb创建一个策略

CREATE RETENTION POLICY "one_day_only" ON "mydb" DURATION 1d REPLICATION 1

示例2:为数据库mydb创建一个默认策略。

CREATE RETENTION POLICY "one_day_only" ON "mydb" DURATION 23h60m REPLICATION 1 DEFAULT

3.修改策略

ALTER RETENTION POLICY <retention_policy_name> ON <database_name> DURATION <duration> REPLICATION <n> SHARD DURATION <duration> DEFAULT

4.删除策略

DROP RETENTION POLICY <retention_policy_name> ON <database_name>

【注意】:策略这个关键词“POLICY”在使用是应该大写,小写应该会出错。
当一个表使用的策略不是默认策略时,在进行操作时一定要显式的指定策略名称,否则会出现错误。

Chronograf介绍

Influxdb在1.3以后版本已经关闭了内置的8086的web管理功能,需要单独的工具来管理。而这个工具就是Chronograf。
其实Chronograf是TICK技术栈的一个组成部分。TICK是InfluxdDB公司推出的监控套件,承包指标采集、分析、画图等时序数据库上下游的工作,有点模仿日志分析系统ELK套件的意思。TICK包含:

  • T = Telegraf is a plugin-driven server agent for collecting and reporting metrics.
  • I = InfluxDB is a time series database built from the ground up to handle high write and query loads.
  • C = Chronograf is a graphing and visualization application for performing ad hoc exploration of data.
  • K = Kapacitor is a data processing framework proving alerting, anomaly detection and action frameworks.

也就是说:

  • Telegraf:数据采集
  • InfluxDB:数据接收和存储
  • Chronograf:数据汇总展示,报警等。
  • Kapacitor:数据处理,比如监控策略等

安装Chronograf

1.安装部署
下载地址:https://portal.influxdata.com/downloads


[root@docdesginer local]# wget https://dl.influxdata.com/chronograf/releases/chronograf-1.3.10.0.x86_64.rpm
[root@docdesginer local]# yum localinstall chronograf-1.3.10.0.x86_64.rpm
[root@docdesginer local]# rpm -ql chronograf
/etc/logrotate.d/chronograf
/usr/bin/chronograf
/usr/lib/chronograf/scripts/chronograf.service
/usr/lib/chronograf/scripts/init.sh
/usr/share/chronograf/canned/apache.json
/usr/share/chronograf/canned/consul.json
/usr/share/chronograf/canned/consul_agent.json
...

2.启动

[root@docdesginer local]# systemctl start chronograf

3.访问Chronograf
浏览器输入http://IP:8888


查询:


在查询时,最好数据库名和表名都加上引号。