Kubernetes监控之InfluxDB

什么是InfluxDB?

InfluxDB介绍

InfluxDB是一款用Go语言编写的开源分布式时序、事件和指标数据库,无需外部依赖。
该数据库现在主要用于存储涉及大量的时间戳数据,如DevOps监控数据,APP metrics, loT传感器数据和实时分析数据。
InfluxDB特征:

  • 无结构(无模式):可以是任意数量的列
  • 可以设置metric的保存时间
  • 支持与时间有关的相关函数(如min、max、sum、count、mean、median等),方便统计
  • 支持存储策略:可以用于数据的删改。(influxDB没有提供数据的删除与修改方法)
  • 支持连续查询:是数据库中自动定时启动的一组语句,和存储策略搭配可以降低InfluxDB的系统占用量。
  • 原生的HTTP支持,内置HTTP API
  • 支持类似sql语法
  • 支持设置数据在集群中的副本数
  • 支持定期采样数据,写入另外的measurement,方便分粒度存储数据。
  • 自带web管理界面,方便使用(登入方式:http://< InfluxDB-IP >:8083)

关键概念

InfluxDB关键概念列表:

||||
| ------- | ------ |
| database| field key | field set |
| field value | measurement | point |
| retention policy | series | tag key |
| tag set | tag value | timestamp |

下面举个例子进行概念介绍:
我们虚拟一组数据,其中有一张数据表(measurement)为census,该表记录了由两个科学家(langstroth和perpetua)在两个不同的位置(1和2),统计了butterflies和honeybees的数据,时间段是2015-08-18 00: 00:00 -- 2015-08-18 06: 12:00. 我们假设这些数据属于叫my_database的数据库(database),且该数据存储在autogen的存储策略(retention policy)中。
数据展示如下:
<pre>
name: census


time butterflies honeybees location scientist
2015-08-18T00:00:00Z 12 23 1 langstroth
2015-08-18T00:00:00Z 1 30 1 perpetua
2015-08-18T00:06:00Z 11 28 1 langstroth
2015-08-18T00:06:00Z 3 28 1 perpetua
2015-08-18T05:54:00Z 2 11 2 langstroth
2015-08-18T06:00:00Z 1 10 2 langstroth
2015-08-18T06:06:00Z 8 23 2 perpetua
2015-08-18T06:12:00Z 7 22 2 perpetua
</pre>

我们针对数据来进行概念分析:
InfluxDB是时序数据库,所以怎么都绕不开时间,第一纵列time存储着时间戳,而时间戳是与数据进行关联,这样才能将时间和数据进行展示。
接下去两纵列(butterflies和honeybees),称为FieldsFields由field keys和field values组成。butterflies和honeybees两个字符串就是field keys;而butterflies这个field key对应的field values就是12 -- 7, honeybees这个field key对应的field values就是23 -- 22。
Field values就是你的数据,它们可以是string、float、int或者bool等。因为influxdb是时序数据库,所以field values总是要和timestamp关联。

field set是在数据层之上应用概念,由field key和field value组成了field set,如这里有8组field set数据:

  • butterflies = 12 honeybees = 23
  • butterflies = 1 honeybees = 30
  • butterflies = 11 honeybees = 28
  • butterflies = 3 honeybees = 28
  • butterflies = 2 honeybees = 11
  • butterflies = 1 honeybees = 10
  • butterflies = 8 honeybees = 23
  • butterflies = 7 honeybees = 22

field是InfluxDB的必要结构,但也需要注意field是没有索引的。

剩下的两个纵列是location和scientist,它们是tagsTags也是由键值对(tag keys和tag values)组成。这里的tag keys是字符串location和scientist;location 这个tag key有两个tag values: 1和2;scientist这个tag key也有两个tag values:perpetua和langstroth。
tag set也是数据之上的概念,是不同的tag key-value组合,这里有4组tag sets数据:

  • location = 1, scientist = langstroth
  • location = 2, scientist = langstroth
  • location = 1, scientist = perpetua
  • location = 2, scientist = perpetua

Tags是可选的参数,也就是说你存储的数据结构中不一定非要带tags,但是它非常好用,因为可以索引。一般都会通过tags来查询数据会快很多。

measurement包含了tags、fields和time,就类似于传统数据库的表。一个measurement可以属于不同的retention policy(存储策略),存储策略描述了InfluxDB怎么去保持数据(DURATION),需要在集群中存储多少份数据副本(REPLICATION)。
示例中的数据都属于census这个measurement,而该measurement又属于autogen这个存储策略。InfluxDB一般都会创建一个default存储策略,它有无限长的持续时间和等于1的副本数。

我们了解过了measurements、tag sets和retention policies的概念后,是时候该知道series了。
在同一个database中,series由retention policy、measurement、tag sets三部分组成,在我们上面的数据中有如下4个series:

Arbitrary series number Retention policy Measurement Tag set
series 1 autogen census location = 1,scientist = langstroth
series 2 autogen census location = 2,scientist = langstroth
series 3 autogen census location = 1,scientist = perpetua
series 4 autogen census location = 2,scientist = perpetua

同一个Series的数据在物理上会按照时间顺序排列存储在一起。
Series的key为measurement + 所有tags的序列化字符串。
代码结构如下:
<pre>
tyep Series struct {
mu sync.RWMutex
Key string
Tags map[string]string
id uint64
measurement *Measurement
}
</pre>

介绍完Series后,就可以解释point了。point是在一个series中有相同时间戳的field set,也可以理解如表里的一行数据。示例中一个Point:
<pre>
name: census


time butterflies honeybees location scientist
2015-08-18T00:00:00Z 1 30 1 perpetua
</pre>

上例中,series由retention policy(autogen), measurement(census)和tag set(location=1,scientist=perpetua)进行定义。而这个point的时间戳则是2015-08-18T 00: 00: 00Z。

InfluxDB Database可以有多个users、continuous queries、retention policy、measurement。因为InfluxDB是一个结构化的数据库,我们可以轻松的去新增measurements、tags、fields。

高级概念:

Retention Policy:

之前讲关键性概念时有简单介绍了RP,这里会进行较详细的介绍。
InfluxDB的数据保留策略(RP)是用来定义数据在数据库中存放的时间,或者定义保存某个期间的数据。
RP在InfluxDB中是比较重要的概念,因为InfluxDB本身是没有提供数据的删除操作,所以需要通过定义RP来控制数据量的问题。
(一个数据库可以有多个RP,但是每个RP必须是独一无二的。)

在具体介绍RP之前,先介绍下另外一个跟RP相关的基础概念(shard)。
shard:
每个RP下面会存在很多shard,每个shard都存储了实际编码和压缩数据,并且不重复。例如你在创建RP时指定了shard duration为1h,那么7--8点存入shard_group0,8--9点就会存入shard_group1中。所以shard才是真实存储InfluxDB数据的地方。
每个shard都属于唯一一个shard group,一个group中会有多个shard;而每个shard包含一组特定的series;所有的points都落在给定的series中,而series是都落在给定的shard group中;

问题1:每个shard group指定了一段时间区域,而且其中有多个shard;每个shard包含一组特定的series。那么shard中存的数据是怎么区分的?series是由RP、meansurement、tags组成,那么shard的区分是根据tags??

shard duration:
shard duration决定了每个shard group存放数据的时间区域。这段时间是在定义RP时由"SHARD DURATION"字段决定。
例如你创建RP时指定了SHARD DURATION为1w,那么每个shard group的时间跨度就为1w,它将包含所有在这一周时间戳内的points。

OK,大概了解了shard之后,继续回到Retention Policy。

当你创建一个数据库时,InfluxDB会自动给你创建一个叫"autogen"的retention Policy,这个RP的数据保留时间是无限。
1.创建RP语法:
<pre>
CREATE RETETION POLICY {rp_name} ON {database_name} DURATION {duration} REPLICATION {n} [SHARD DURATION {duration}] [DEFAULT]
</pre>

注:
DURATION: 用于描述数据保留时间。可设置的时间区间是1h -- INF(无穷大)。
REPLICATION: 用于指定数据的备份数量,n是表示数据节点的数量。
SHARD DURATION: 用于指定shard group的时间区域,这个字段的duration是不支持INF的。默认情况下,shard group的duration由RP的duration决定。

Retention Policy's DURATION Shard Group Duration
< 2 days 1h
>= 2 days and <= 6 mouths 1day
> 6 mouths 7days

DEFAULT: 可选参数,用于指定使用新的RP来作为数据库的默认RP。(具体新在哪?需要进一步查看)

2.修改RP语法:
<pre>
ALTER RETENTION POLICY {rp_name} ON {database_name} DURATION {duration} REPLICATION {n} SHARD DURATION {duration} DEFAULT
</pre>

注:
后面的参数字段都一样,主要差别就在于关键字段:ALTER RETENTION POLICY

3.删除RP语法:
<pre>
DROP RETENTION POLICY {rp_name} ON {database_name}
</pre>

注:
即使你企图去删除一个不存在的rp,命令返回值也是空,不会返回一个错误码。

Continuous Queries:

之前我们介绍了数据保存策略,数据超过保存策略里指定的时间之后,就会被删除。但我们不想完全删除这些数据,比如我们想把每秒的监控数据至少保留成每小时,就需要用到连续查询(Continuous Queries)功能。
连续查询主要用在将数据归档,以降低系统空间的占用率,但这主要是以降低数据精度为代价。
基本语法:
<pre>
CREATE CONTINUOUS QUERY {cq_name} ON {database_name}
BEGIN
{cq_query}
END
注:cq_name表示创建的Continuous query的名字;database_name表示要操作的数据库。

cq_query是操作函数,如下:
SELECT {function[s]} INTO {destnation_measurement} FROM {measurement} [WHERE {stuff}] GROUP BY time({interval})[,{tag_key[s]}]
注:destnation_measurement表示新生成的数据存放的表;measurement表示数据查询的表;
GROUP BY time表示采样分析的数据时间,比如设置1h,如果当前是17:00,那么需要计算的数据时间就是16:00 -- 16:59。
</pre>

例子1: 自动降低精度来采样数据
<pre>
CREATE CONTINUOUS QUERY "cq_basic" ON "transportation"
BEGIN
SELECT mean("passengers") INTO "average_passengers" FROM "bus_data" GROUP BY time(1h)
END

查看结果:

SELECT * FROM "average_passengers"
name: average_passengers


time mean
2016-08-28T07:00:00Z 7
2016-08-28T08:00:00Z 13.75
</pre>

连续查询(cq_basic)通过在数据库"transportation"中的"bus_data"表,计算每小时平均的旅客数,然后在该数据库中新建"average_passengers"表,并将数据存入该表中。该cq_basic每小时执行一遍,然后将每个小时的point写入表中。

例子2:自动降低精度来采样数据,并将数据存入另外一个Retention Policy(RP)
<pre>
CREATE CONTINUOUS QUERY "cq_basic_rp" ON "transportation"
BEGIN
SELECT mean("passengers") INTO "transportation"."three_weeks"."average_passengers" FROM "bus_data" GROUP BY time(1h)
END

查看结果:

SELECT * FROM "transportation"."three_weeks"."average_passengers"
name: average_passengers


time mean
2016-08-28T07:00:00Z 7
2016-08-28T08:00:00Z 13.75
</pre>

连续查询(cq_basic_rp)通过在数据库"transportation"中的"bus_data"表,计算每小时平均的旅客数,然后将数据存入transportation数据库中的three_weeks(RP)的average_passengers表中。该cq_basic_rp每小时执行一遍,然后将每个小时的point写入表中。

例子3:采用通配符,自动降低精度采样数据
<pre>
CREATE CONTINUOUS QUERY "cq_basic_br" ON "transportation"
BEGIN
SELECT mean() INTO "dowmsample_transportation"."autogen".:MEASUREMENT FROM /./ GROUP BY time(30m),*
END

查看结果:

SELECT * FROM "downsample_transportation"."autogen"."bus_data"
name: bus_data


time mean_complaints mean_passengers
2016-08-28T07:00:00Z 9 6.5
2016-08-28T07:30:00Z 9 7.5
2016-08-28T08:00:00Z 8 11.5
2016-08-28T08:30:00Z 7 16
</pre>

连续查询(cq_basic_br),计算数据库(transportation)中每张表(这里只有一张表"bus_data"),每30分钟平均的旅客数和投诉量,然后将数据存入downsample_transportation数据库中的autogen(RP)中。该cq_basic_br每30分钟执行一遍,然后将每个小时的point写入表中。

例子4:配置CQ的时间偏移,来采集数据:
<pre>
CREATE CONTINUOUS QUERY "cq_basic_offset" ON "transportation"
BEGIN
SELECT mean("passengers") INTO "average_passengers" FROM "bus_data" GROUP BY time(1h,15m)
END

查看结果:

SELECT * FROM "average_passengers"
name: average_passengers


time mean
2016-08-28T07:15:00Z 7.75 //注意时间是从7:15 -- 8:15
2016-08-28T08:15:00Z 16.75
</pre>

该CQ(cq_basic_offset),设置了每整点往后偏移15分钟,再进行每小时的平均值计算。比如会将8 : 15--9: 15,来代替8: 00--9: 00。

高级语法:
<pre>
CREATE CONTINUOUS QUERY {cq_name} ON {database_name}
RESAMPLE EVERY {val1} FOR {val2}
BEGIN
{cq_query}
END

注意: cq_name、database_name、cq_query和之前的基本语法都一致。
EVERY后面带的时间,表示每val1点时间就触发一次数据采样,而数据的区间是和cq_query、FOR有关。在这段时间内每val1点时间再采集一次。比如cq_query设置1h,val1设置为30m,表示在1h内会有两次数据计算。比如8点--9点之间就会有两次数据的计算,第一次计算是8:30触发的,计算的区间是8:00--8:30,第二次计算是9:00触发的,计算的区间是8:00--9:00。在目的数据库中,默认第二次的计算结果会覆盖第一次的计算结果。
FOR后面带的时间,表示修改了cq_query计算的数据区间,比如cq_query时间设置为30m,val2设置的是1h。那么cq每30m会触发一次数据计算,计算的区间是(now-1h)--now。
</pre>

示例数据: 给下面的例子使用
<pre>
name: bus_data


time passengers
2016-08-28T06:30:00Z 2
2016-08-28T06:45:00Z 4
2016-08-28T07:00:00Z 5
2016-08-28T07:15:00Z 8
2016-08-28T07:30:00Z 8
2016-08-28T07:45:00Z 7
2016-08-28T08:00:00Z 8
2016-08-28T08:15:00Z 15
2016-08-28T08:30:00Z 15
2016-08-28T08:45:00Z 17
2016-08-28T09:00:00Z 20
</pre>

例子1:配置执行间隔
<pre>
CREATE CONTINUOUS QUERY "cq_advanced_every" ON "transportation"
RESAMPLE EVERY 30m
BEGIN
SELECT mean("passengers") INTO "average_passengers" FROM "bus_data" GROUP BY time(1h)
END

中间的执行过程:
At 8:00, cq_advanced_every executes a query with the time range WHERE time >= '7:00' AND time < '8:00'.
cq_advanced_every writes one point to the average_passengers measurement:
name: average_passengers


time mean
2016-08-28T07:00:00Z 7

At 8:30, cq_advanced_every executes a query with the time range WHERE time >= '8:00' AND time < '9:00'.
cq_advanced_every writes one point to the average_passengers measurement:
name: average_passengers


time mean
2016-08-28T08:00:00Z 12.6667

At 9:00, cq_advanced_every executes a query with the time range WHERE time >= '8:00' AND time < '9:00'.
cq_advanced_every writes one point to the average_passengers measurement:
name: average_passengers


time mean
2016-08-28T08:00:00Z 13.75

查看结果:

SELECT * FROM "average_passengers"
name: average_passengers


time mean
2016-08-28T07:00:00Z 7
2016-08-28T08:00:00Z 13.75
</pre>

cq_advanced_every在8点--9点执行了两次。第一次8:30触发,因为cq_query设置了1h,所以数据区间是8: 00--9: 00,但因为是在8:30触发的,8: 30--9: 00的数据还没产生呢,所以实际采集的数据区间是在8: 00--8: 30,即数据(8, 15, 15), 计算的平均值为12.6667;第二次9:00触发,计算的区间是8: 00--9: 00,即数据(8, 15, 15, 17),计算的平均值为13.75.

例子2:配置重采样的时间区间
<pre>
CREATE CONTINUOUS QUERY "cq_advanced_for" ON "transportation"
RESAMPLE FOR 1h
BEGIN
SELECT mean("passengers") INTO "average_passengers" FROM "bus_data" GROUP BY time(30m)
END

采样过程:
At 8:00 cq_advanced_for executes a query with the time range WHERE time >= '7:00' AND time < '8:00'.
cq_advanced_for writes two points to the average_passengers measurement:
name: average_passengers


time mean
2016-08-28T07:00:00Z 6.5
2016-08-28T07:30:00Z 7.5

At 8:30 cq_advanced_for executes a query with the time range WHERE time >= '7:30' AND time < '8:30'.
cq_advanced_for writes two points to the average_passengers measurement:
name: average_passengers


time mean
2016-08-28T07:30:00Z 7.5
2016-08-28T08:00:00Z 11.5

At 9:00 cq_advanced_for executes a query with the time range WHERE time >= '8:00' AND time < '9:00'.
cq_advanced_for writes two points to the average_passengers measurement:
name: average_passengers


time mean
2016-08-28T08:00:00Z 11.5
2016-08-28T08:30:00Z 16

结果查询:

SELECT * FROM "average_passengers"
name: average_passengers


time mean
2016-08-28T07:00:00Z 6.5
2016-08-28T07:30:00Z 7.5
2016-08-28T08:00:00Z 11.5
2016-08-28T08:30:00Z 16
</pre>

该cq_advanced_for,每30m重采样一次,采样的区间是(now-1h -- now), 也就是每触发一次执行,就会进行两次计算。因为采样的区间是1h,而需要计算的是每30m的平均值。

例子3:配置cq的执行区间和时间范围
<pre>
CREATE CONTINUOUS QUERY "cq_advanced_every_for" ON "transportation"
RESAMPLE EVERY 1h FOR 90m
BEGIN
SELECT mean("passengers") INTO "average_passengers" FROM "bus_data" GROUP BY time(30m)
END

采样过程:
At 8:00 cq_advanced_every_for executes a query with the time range WHERE time >= '6:30' AND time < '8:00'.
cq_advanced_every_for writes three points to the average_passengers measurement:
name: average_passengers


time mean
2016-08-28T06:30:00Z 3
2016-08-28T07:00:00Z 6.5
2016-08-28T07:30:00Z 7.5

At 9:00 cq_advanced_every_for executes a query with the time range WHERE time >= '7:30' AND time < '9:00'.
cq_advanced_every_for writes three points to the average_passengers measurement:
name: average_passengers


time mean
2016-08-28T07:30:00Z 7.5
2016-08-28T08:00:00Z 11.5
2016-08-28T08:30:00Z 16

结果查询:

SELECT * FROM "average_passengers"
name: average_passengers


time mean
2016-08-28T06:30:00Z 3
2016-08-28T07:00:00Z 6.5
2016-08-28T07:30:00Z 7.5
2016-08-28T08:00:00Z 11.5
2016-08-28T08:30:00Z 16
</pre>

该cq_advanced_every_for,需要计算30m的平均值,每1小时触发一次cq执行,采样的数据区间是90m,所以每触发一次就会计算3次平均值。

例子4:配置CQ的采样时间区间,并且填充空结果
<pre>
CREATE CONTINUOUS QUERY "cq_advanced_for_fill" ON "transportation"
RESAMPLE FOR 2h
BEGIN
SELECT mean("passengers") INTO "average_passengers" FROM "bus_data" GROUP BY time(1h) fill(1000)
END

采样过程:
At 6:00, cq_advanced_for_fill executes a query with the time range WHERE time >= '4:00' AND time < '6:00'.
cq_advanced_for_fill writes nothing to average_passengers; bus_data has no data that fall within that time range.

At 7:00, cq_advanced_for_fill executes a query with the time range WHERE time >= '5:00' AND time < '7:00'.
cq_advanced_for_fill writes two points to average_passengers:
name: average_passengers


time mean
2016-08-28T05:00:00Z 1000 <------ fill(1000)
2016-08-28T06:00:00Z 3 <------ average of 2 and 4

[…]

At 11:00, cq_advanced_for_fill executes a query with the time range WHERE time >= '9:00' AND time < '11:00'.
cq_advanced_for_fill writes two points to average_passengers:
name: average_passengers


2016-08-28T09:00:00Z 20 <------ average of 20
2016-08-28T10:00:00Z 1000 <------ fill(1000)

At 12:00, cq_advanced_for_fill executes a query with the time range WHERE time >= '10:00' AND time < '12:00'.
cq_advanced_for_fill writes nothing to average_passengers; bus_data has no data that fall within that time range.

结果查询:

SELECT * FROM "average_passengers"
name: average_passengers


time mean
2016-08-28T05:00:00Z 1000
2016-08-28T06:00:00Z 3
2016-08-28T07:00:00Z 7
2016-08-28T08:00:00Z 13.75
2016-08-28T09:00:00Z 20
2016-08-28T10:00:00Z 1000
</pre>

该cq_advcanced_for_fill,增加了空数据区的默认值填充,使用fill(value)来实现。

连续查询使用案例:
1.实现重采样和数据保留:
使用CQ和retention policy配合达到该功能。可以降低数据库存储压力。

2.预先计算来解决费时的查询:
CQ会自动进行重采样,将高精度的数据转换为低精度的数据。低精度的数据查询会耗费更少的资源和时间。

3.替代HAVING条款:
InfluxDB不支持HAVING字段,需要使用CQ+别的命令来实现替换。
例子:
<pre>
SELECT mean("bees") FROM "farm" GROUP BY time(30m) HAVING mean("bees") > 20
</pre>

以上的命令,InfluxDB不支持。其实就是需要实现采集30m的平均值,然后取那些大于20的值。
InfluxDB的替代方案:

  • 先创建CQ:
    <pre>
    CREATE CONTINUOUS QUERY "bee_cq" ON "mydb"
    BEGIN
    SELECT mean("bees") AS "mean_bees" INTO "aggregate_bees" FROM "farm" GROUP BY time(30m)
    END
    </pre>
    该创建的CQ,每30m进行bees的平均值计算,并将结果写入aggregate_bees表中的mean_bees field中。
  • 查询CQ结果:
    这一步就是需要运行HAVING mean("bees") > 20这条命令。InfluxDB命令使用如下:
    <pre>
    SELECT "mean_bees" FROM "aggregate_bees" WHERE "mean_bees" > 20
    </pre>

4.替代内嵌函数:
InfluxDB不支持内嵌函数,比如:
<pre>
SELECT mean(count("bees")) FROM "farm" GROUP BY time(30m)
</pre>

替换上述方案:

  • 创建CQ:
    <pre>
    CREATE CONTINUOUS QUERY "bee_cq" ON "mydb"
    BEGIN
    SELECT count("bees") AS "count_bees" INTO "aggregate_bees" FROM "farm" GROUP BY time(30m)
    END
    </pre>
  • 查询CQ结果:
    这一步就是需要执行mean([...])这条命令,其实就是计算某段区间的count("bees")平均值,如下:
    <pre>
    SELECT mean("count_bees") FROM "aggregate_bees" WHERE time >= {start_time} AND time <= {end_time}
    </pre>

Kapacitor是InfluxData的数据处理引擎,它可以达到CQ一样的功能。参考HERE

InfluxDB使用

数据库配置

参考Here

Database

1.查询:
<pre>
SHOW DATABASES
</pre>

2.创建:
<pre>
CREATE DATABASE {database_name} [WITH [DURATION <duration>] [REPLICATION <n>] [SHARD DURATION <duration>] [NAME <retention-policy-name>]]
注:WITH带的这段属性,就是Retention Policy的,可以参考它。
</pre>

3.删除:
<pre>
DROP DATABASE {database_name}
</pre>

RETENTION POLICY

1.查询:
<pre>
SHOW RETETION POLICIES
</pre>

2.创建:
<pre>
CREATE RETENTION POLICY {retention_policy_name} ON {database_name} DURATION {duration} REPLICATION {n} [SHARD DURATION {duration}] [DEFAULT]
</pre>

3.修改:
<pre>
ALTER RETENTION POLICY {rp_name} ON {database_name} DURATION {duration} REPLICATION {n} SHARD DURATION {duration} DEFAULT
</pre>

4.删除:
<pre>
DROP RETENTION POLICY {rp_name} ON {database_name}
</pre>

CONTINUOUS QUERY:

1.查询:
<pre>
SHOW CONTINUOUS QUERY
</pre>

2.创建:
<pre>
参考之前的例子,介绍了较多的创建方式。
</pre>

3.删除:
<pre>
DROP CONTINUOUS QUERY {cq_name} ON {database_name}
</pre>

举了部分例子,具体的可以再查看官方资料。

API

InfluxDB API提供了较简单的方式用于数据库交互。该API使用了HTTP的方式,并以JSON格式进行返回。
下面对API进行介绍:

支持的Endpoints:

Endpoint 描述
/ping 使用/ping用于检查InfluxDB的状态或者版本信息
/query 使用/query用于查询数据,管理数据库、rp、users等
/write 使用/write去写数据到数据库中

/ping

/ping支持GET和HEAD,都可用于获取指定信息。
定义:

示例:
获取InfluxDB版本信息:
<pre>
$ curl -sl -I http://localhost:8086/ping
HTTP/1.1 204 No Content
Request-Id: 245a330d-baba-11e6-8098-000000000000
X-Influxdb-Version: 0.9.4.1
Date: Mon, 05 Dec 2016 07:12:11 GMT
</pre>

/query

/query支持GET和POST的HTTP请求。可用于查询数据和管理数据库、rp、users。
定义:

用法说明:

动作 查询类型
GET 用于所有数据的查询:
SELECT *
SHOW
POST 支持的动作如下:
ALTER
CREATE
DELETE
DROP
GRANT
KILL
REVOKE

只有SELECT特殊点,支持INTO字段

示例:
1.使用SELECT查询数据:
<pre>
$ curl -G 'http://localhost:8086/query?db=mydb' --data-urlencode 'q=SELECT * FROM "mymeas"'

{"results":[{"series":[{"name":"mymeas","columns":["time","myfield","mytag1","mytag2"],"values":[["2016-05-20T21:30:00Z",12,"1",null],["2016-05-20T21:30:20Z",11,"2",null],["2016-05-20T21:30:40Z",18,null,"1"],["2016-05-20T21:31:00Z",19,null,"3"]]}]}]}
</pre>

再使用额外的INTO字段:
<pre>
$ curl -XPOST 'http://localhost:8086/query?db=mydb' --data-urlencode 'q=SELECT * INTO "newmeas" FROM "mymeas"'

{"results":[{"series":[{"name":"result","columns":["time","written"],"values":[["1970-01-01T00:00:00Z",4]]}]}]}
</pre>

2.创建数据库:
<pre>
$ curl -XPOST 'http://localhost:8086/query' --data-urlencode 'q=CREATE DATABASE "mydb"'

{"results":[{}]}
</pre>

Query参数说明:

参数 是否可选 描述
chunked=[true or {number_of_points}] 可选 返回批量的points信息,以代替单个响应。设置成true,InfluxDB返回一批series或者10000个points;或者设置对应的points数量
db={db_name} 必选 设置数据库名
epoch=[h,m,s,ms,u,ns] 可选 指定时间戳的精度,默认是ns
p={password} 可选 如果设置了认证,则需要用户密码
pretty=true 可选 优化输出格式,设置之后会议json格式进行输出,利于调试
rp={rp_name} 可选 设置查询的rp。如果没有设置,则查询默认的rp
u={username} 可选 如果设置了认证,则需要用户密码

示例1:使用http认证来创建数据库:
<pre>
$ curl -XPOST 'http://localhost:8086/query?u=myusername&p=mypassword' --data-urlencode 'q=CREATE DATABASE "mydb"'

{"results":[{}]}
</pre>

示例2:使用基础认证来创建数据库:
<pre>
$ curl -XPOST -u myusername:mypassword 'http://localhost:8086/query' --data-urlencode 'q=CREATE DATABASE "mydb"'

{"results":[{}]}
</pre>

数据请求体:
<pre>
--data-urlencode 'q=< influxDB query >'
</pre>

  • 可支持多条请求命令: 需要使用分号(;),来进行命令分隔

  • 可支持导入文件的格式进行查询: 如果文件中使用了多条请求命令,则也需要使用分号(;)进行分隔
    <pre>
    语法:
    curl -F "q=@<path_to_file>" -F "async=true" http://localhost:8086/query
    </pre>

  • 以CSV的格式返回请求结果:
    <pre>
    语法:
    curl -H "Accept: application/csv" -G 'http://localhost:8086/query [...]
    </pre>

  • 支持绑定参数:
    该API支持使用WHERE绑定参数,来进行指定field values或者tag vaules。
    <pre>
    Query语法:
    --data-urlencode 'q= SELECT [...] WHERE [ < field_key > | < tag_key > ] = $< placeholder_key >'

    Map语法:
    --data-urlencode 'params={"< placeholder_key >":[ < placeholder_float_field_value > | < placeholder_integer_field_value > | "< placeholder_string_field_value >" | < placeholder_boolean_field_value > | "< placeholder_tag_value >" ]}'
    </pre>

示例1:发送多条Query命令
<pre>
$ curl -G 'http://localhost:8086/query?db=mydb&epoch=s' --data-urlencode 'q=SELECT * FROM "mymeas";SELECT mean("myfield") FROM "mymeas"'

{"results":[{"series":[{"name":"mymeas","columns":["time","myfield","mytag1","mytag2"],"values":[[1463779800,12,"1",null],[1463779820,11,"2",null],[1463779840,18,null,"1"],[1463779860,19,null,"3"]]}]},{"series":[{"name":"mymeas","columns":["time","mean"],"values":[[0,15]]}]}]}
</pre>

示例2:以CSV格式返回请求结果
<pre>
curl -H "Accept: application/csv" -G 'http://localhost:8086/query?db=mydb' --data-urlencode 'q=SELECT * FROM "mymeas" LIMIT 3'

name,tags,time,tag1,tag2,value
mymeas,,1478030187213306198,blue,tag2,23
mymeas,,1478030189872408710,blue,tag2,44
mymeas,,1478030203683809554,blue,yellow,101
</pre>

示例3:通过文件的形式导入Queries
<pre>
curl -F "q=@queries.txt" -F "async=true" 'http://localhost:8086/query'
文本内容如下:
CREATE DATABASE mydb;
CREATE RETENTION POLICY four_weeks ON mydb DURATION 4w REPLICATION 1;
</pre>

示例4:通过WHERE字段指定tag value
<pre>
curl -G 'http://localhost:8086/query?db=mydb' --data-urlencode 'q=SELECT * FROM "mymeas" WHERE "mytagkey" = $tag_value' --data-urlencode 'params={"tag_value":"mytagvalue1"}'

{"results":[{"series":[{"name":"mymeas","columns":["time","myfieldkey","mytagkey"],"values":[["2016-09-05T18:25:08.479629934Z",9,"mytagvalue1"],["2016-09-05T18:25:20.892472038Z",8,"mytagvalue1"],["2016-09-05T18:25:30.408555195Z",10,"mytagvalue1"],["2016-09-05T18:25:39.108978991Z",111,"mytagvalue1"]]}]}]}
</pre>

示例5:通过WHERE字段指定数字区间
<pre>
curl -G 'http://localhost:8086/query?db=mydb' --data-urlencode 'q=SELECT * FROM "mymeas" WHERE "myfieldkey" > $field_value' --data-urlencode 'params={"field_value":9}'

{"results":[{"series":[{"name":"mymeas","columns":["time","myfieldkey","mytagkey"],"values":[["2016-09-05T18:25:30.408555195Z",10,"mytagvalue1"],["2016-09-05T18:25:39.108978991Z",111,"mytagvalue1"],["2016-09-05T18:25:46.587728107Z",111,"mytagvalue2"]]}]}]}
</pre>

示例6:通过WHERE字段指定多个条件
<pre>
curl -G 'http://localhost:8086/query?db=mydb' --data-urlencode 'q=SELECT * FROM "mymeas" WHERE "mytagkey" = $tag_value AND "myfieldkey" > $field_value' --data-urlencode 'params={"tag_value":"mytagvalue2","field_value":9}'

{"results":[{"series":[{"name":"mymeas","columns":["time","myfieldkey","mytagkey"],"values":[["2016-09-05T18:25:46.587728107Z",111,"mytagvalue2"]]}]}]}
</pre>

/write

/wirte只支持POST的HTTP请求,使用该Endpoint可以写数据到已存在的数据库中。
定义:
POST http://localhost:8086/write

Query参数说明:

参数 是否可选 描述
consistency=[any,one,quorum,all] 可选 设置point的写入一致性,默认是one.详细的请参考HERE
db={db_name} 必选 设置数据库名
precision=[h,m,s,ms,u,n] 可选 指定时间戳的精度,默认是ns
p={password} 可选 如果设置了认证,则需要用户密码
rp={rp_name} 可选 设置查询的rp。如果没有设置,则查询默认的rp
u={username} 可选 如果设置了认证,则需要用户密码

示例1:使用秒级的时间戳,将一个point写入数据库mydb
<pre>
$ curl -i -XPOST "http://localhost:8086/write?db=mydb&precision=s" --data-binary 'mymeas,mytag=1 myfield=90 1463683075'
</pre>

示例2:将一个point写入数据库mydb,并指定RP为myrp
<pre>
$ curl -i -XPOST "http://localhost:8086/write?db=mydb&rp=myrp" --data-binary 'mymeas,mytag=1 myfield=90'
</pre>

示例3:使用HTTP认证的方式,将一个point写入数据库mydb
<pre>
$ curl -i -XPOST "http://localhost:8086/write?db=mydb&u=myusername&p=mypassword" --data-binary 'mymeas,mytag=1 myfield=91'
</pre>

示例4:使用基础认证的方式,将一个point写入数据库mydb
<pre>
$ curl -i -XPOST -u myusername:mypassword "http://localhost:8086/write?db=mydb" --data-binary 'mymeas,mytag=1 myfield=91'
</pre>

数据请求体:
<pre>
--data-binary '< Data in Line Protocol format >'
</pre>

所有写入的数据必须是二进制,且使用Line Protocol格式。

示例1:写多个points到数据库中,需要使用新的一行
<pre>
$ curl -i -XPOST "http://localhost:8086/write?db=mydb" --data-binary 'mymeas,mytag=3 myfield=89
mymeas,mytag=2 myfield=34 1463689152000000000'
</pre>

示例2:通过导入文件的形式,写入多个points。需要使用@来指定文件
<pre>
$ curl -i -XPOST "http://localhost:8086/write?db=mydb" --data-binary @data.txt
文件内容如下
mymeas,mytag1=1 value=21 1463689680000000000
mymeas,mytag1=1 value=34 1463689690000000000
mymeas,mytag2=8 value=78 1463689700000000000
mymeas,mytag3=9 value=89 1463689710000000000
</pre>

响应的状态码:

HTTP状态码 描述
204 No Content 成功
400 Bad Request 不能接受的请求。可能是Line Protocol语法错误;写入错误的field values类型;等。。
404 Not Fount 不能接受的请求。可能是数据库不存在,或者别的原因
500 Internal Server Error 系统超负荷了或者明显受损。可能是用户企图去写一个不存在的RP。或者别的原因

参考资料:

1.官方概念介绍: https://docs.influxdata.com/influxdb/v1.1/concepts/key_concepts/
2.InfluxDB详解之TSM存储引擎解析(一): http://blog.fatedier.com/2016/08/05/detailed-in-influxdb-tsm-storage-engine-one/
 InfuxDB详解之TSM存储引擎解析(二):http://blog.fatedier.com/2016/08/15/detailed-in-influxdb-tsm-storage-engine-two/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • InfluxDB是一个开源的时序数据库,使用GO语言开发,特别适合用于处理和分析资源监控数据这种时序相关数据。而I...
    __七把刀__阅读 164,479评论 19 91
  • 随着线上服务的全面docker化,对docker容器的监控就很重要了。SA的监控系统是物理机的监控,在一个物理机跑...
    __七把刀__阅读 14,103评论 3 22
  • 为什么选择InfluxDB 安装 查询、插入、删除数据 命令行形式 HTTP APIs /ping /query ...
    YouzuDevOps阅读 6,751评论 0 5
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,580评论 18 139
  • 人到四十,什么都该看明白了。自认为活的问心无愧,到头来缺体无完肤。
    莫失莫忘_8437阅读 236评论 0 2