InfluxDB v1.x

Table of Contents

Retention policy DURATION 决定 InfluxDB 保留数据的时长。 SHARD DURATION 决定子语句确定分片组覆盖的时间范围。对应关系:

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

1. InfluxQL

1.1. SELECT 语句

SELECT <field_key>[,<field_key>,<tag_key>] FROM <measurement_name>[,<measurement_name>]

当 SELECT 中包含 tag 时,只要需要同时包含一个 field。当 tag 和 field 的名字相同的时候可以携带标识符类型来区分。 比如: "<field_key>"::field 表示 field, "<tag_key>::tag" 表示 tag。

1.2. FROM 语句

FROM 语句支持一个或者多个 measurement(s):

  • FROM <measurement_name> 查询单个表
  • FROM <measurement_name>,<measurement_name> 查询多个表
  • FROM <database_name>.<retention_policy_name>.<measurement_name> 指定数据库和保留策略
  • FROM <database_name>..<measurement_name> 指定数据库,使用默认的保留策略

1.2.1. 引号

如果标识符包含除了 [A-z,0-9,_] 以外的字符、以数字开头或者是 InfluxQL 关键则,那么标识符必须用双引号引起来。 虽然不总是必要,但是建议你使用双引号。

1.2.2. 范例

查询所有的 fields SELECT *::field ,但是不能通过这个方法来查询所有的 tags。

数学运算: SELECT ("water_level" * 2) + 4 FROM "h2o_feet"

常见 SELECT 问题:在 SELECT 中只包含 tag,会查询不到数据。

1.3. WHERE 语句

WHERE 基于 fields,tags 和 timestamps 的过滤。

SELECT_clause FROM_clause WHERE <conditional_expression> [(AND|OR) <conditional_expression> [...]]

注意 InfluxDB 不支持在 WHERE 语句中用多个时间范围之间用 OR 运算。如下语句会返回空:

> SELECT * FROM "absolutismus" WHERE time = '2016-07-31T20:07:00Z' OR time = '2016-07-31T23:07:17Z'

1.3.1. Fields

field_key <operator> ['string' | boolean | float | integer]

field 值支持字符串,布尔,浮点型和整型比较。 WHERE 中字符串使用单引号。

支持的比较运算符:

Operator Meaning
= 等于
<> 不等于
!= 不等于
> 大于
>= 大于等于
< 小于
<= 小于等于

1.3.2. Tags

tag_key <operator> ['tag_value']

tags 的值要使用单引号。支持的运算符:

Operator Meaning
= 等于
<> 不等于
!= 不等于

1.3.3. Timestamps

对于大部分的 SELECT 语句,默认的时间范围是 1677-09-21T00:12:43.145224194Z2262-04-11T23:47:16.854775806Z 之间。

SELECT 使用 GROUP BY time() 时,默认的时间范围是 1677-09-21T00:12:43.145224194Znow() 之间。

1.4. GROUP BY 语句

GROUP BY 对查询结果进行分组:

  • 基于一个或者多个 tags
  • 指定时间间隔

注意: 你不可以对 fields 使用 GROUP BY

1.4.1. GROUP BY tags

SELECT_clause FROM_clause [WHERE_clause] GROUP BY [* | <tag_key>[,<tag_key]]

GROUP BY * 按照所有 tag 分组

GROUP BY <tag_key> 按照单个 tag 分组

GROUP BY <tag_key>,<tag_key> 多个 tag 分组,tag 的顺序无关紧要

如果包含 WHERE 语句, GROUP BY 语句必须出现在 WHERE 之后

1.4.2. GROUP BY time intervals

1.4.2.1. Basic GROUP BY time() syntax
SELECT <function>(<field_key>) FROM_clause WHERE <time_range> GROUP BY time(<time_interval>),[tag_key] [fill(<fill_option>)]
  • time(time_interval) 按照持续时间进行分组
  • fill(<fill_option>) 可选的,它会更改为没有数据的时间间隔报告的值
1.4.2.2. Advanced GROUP BY time() syntax
SELECT <function>(<field_key>) FROM_clause WHERE <time_range> GROUP BY time(<time_interval>,<offset_interval>),[tag_key] [fill(<fill_option>)]

1.5. INTO 语法

INTO 将查询结果写入到用户指定的 measurment。

SELECT_clause INTO <measurement_name> FROM_clause [WHERE_clause] [GROUP_BY_clause]

measurement_name 与 FROM 后紧跟的库表语法规范类似。

1.6. ORDER BY time DESC

SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] [GROUP_BY_clause] ORDER BY time DESC

如果包含 GROUP BY 条件的话, ORDER by time DESC 必须出现在 GROUP BY 之后。如果查询包含 WHERE 但是没有 GROUP BY 条件, ORDER by time DESC 必须在 WHERE 之后。

1.7. LIMIT 和 SLIMIT 语句

LIMITSLIMIT 限制 points 和 series 查询的返回数量。

1.7.1. LIMIT 语句

SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] [GROUP_BY_clause] [ORDER_BY_clause] LIMIT <N>

注意 LIMIT 必须放在上面所有语句的最后。

1.7.2. SLIMIT 语句

SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] GROUP BY *[,time(<time_interval>)] [ORDER_BY_clause] SLIMIT <N>

1.8. OFFSET 和 SOFFSET 语句

OFFSET <N> 对查询结果进行 N points 的分页。

SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] [GROUP_BY_clause] [ORDER_BY_clause] LIMIT_clause OFFSET <N> [SLIMIT_clause]

OFFSET 需要和 LIMIT 一起使用,否则会导致查询结果不一致。整体表达的是: OFFSET 之后的 LIMIT 个元素。

1.9. 时区(time zone)语句

tz() 语句指定时区1

SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] [GROUP_BY_clause] [ORDER_BY_clause] [LIMIT_clause] [OFFSET_clause] [SLIMIT_clause] [SOFFSET_clause] tz('<time_zone>')

默认情况下,InfluxDB 存储和返回 UTC 时间戳。

2. 监控

2.1. InfluxDB _internal 1.x 表和字段

https://docs.influxdata.com/platform/monitoring/influxdata-platform/tools/measurements-internal/

默认情况下,InfluxDB 生成内部的指标保存到 _internal 库中。

2.1.1. 在生产环境下禁用 _internal 库

InfluxData 不推荐在生产集群中使用 _internal 。它带来了不必要的开销,特别是集群比较忙的情况下,会加重集群的复杂。 _internal 数据库中存储的指标主要衡量工作负载性能,只能在非生产环境使用。

InfluxDB 配置文件将 [monitor] 下的 store-enabled 设置成 false 可以关闭 _internal 数据库。

# ...
[monitor]
  # ...
  # Whether to record statistics internally.
  store-enabled = false
  #...

2.1.2. 将内部指标存储在外部监控中

在生产的集群中 InfluxDB _internal 指标,使用 Telegraf 和 influxdb 输入插件 来捕获 /debug/vars 端点下的指标然后存储在外部的 InfluxDB 监控实例中。具体看:配置监控的监控

2.1.3. 那 InfluxDB 生产的实例到底怎么监控呢?

  1. InfluxDB 实例会暴露 http://localhost:8086/debug/vars
  2. 本机的 Telegraf 添加 InfluxDB Input 插件
  3. Telegraf 配置数据暴露给 Prometheus
  4. Prometheus 新增 Target

3. FAQ

3.1. InfluxDB 如何处理重复的点?

Point(点)由表名,tag 集合和时间戳唯一标识。如果你提交的一个 point 和现有的 point 有相同的标识,fields 集合会变成新的 field 和老的 field 的合集,关联关系会指向新的 field 集合。这是预料中的事。

比如:

  • Old point: cpu_load,hostname=server02,az=us_west val_1=24.5,val_2=7 1234567890000000
  • New point: cpu_load,hostname=server02,az=us_west val_1=5.24 1234567890000000

提交新的 point 之后,InfluxDB 会覆写 val_1 的新值, 不管 val_2 。最终的结果是:

> SELECT * FROM "cpu_load" WHERE time = 1234567890000000
name: cpu_load
--------------
time                      az        hostname   val_1   val_2
1970-01-15T06:56:07.89Z   us_west   server02   5.24    7

为了存储这两个 points:

  • 引入一个任意的新标签来强制保持唯一

    Old point: cpu_load,hostname=server02,az=us_west,uniq=1 val_1=24.5,val_2=7 1234567890000000

    New point: cpu_load,hostname=server02,az=us_west,uniq=2 val_1=5.24 1234567890000000

    在 New point 写入到 InfluxDB 之后:

    > SELECT * FROM "cpu_load" WHERE time = 1234567890000000
    name: cpu_load
    --------------
    time                      az        hostname   uniq   val_1   val_2
    1970-01-15T06:56:07.89Z   us_west   server02   1      24.5    7
    1970-01-15T06:56:07.89Z   us_west   server02   2      5.24
    
    
  • 时间上增加一个纳秒

    Old point: cpu_load,hostname=server02,az=us_west,uniq=1 val_1=24.5,val_2=7 1234567890000000

    New point: cpu_load,hostname=server02,az=us_west,uniq=2 val_1=5.24 1234567890000000

    在 New point 写入到 InfluxDB 之后:

    > SELECT * FROM "cpu_load" WHERE time >= 1234567890000000 and time <= 1234567890000001
    name: cpu_load
    --------------
    time                             az        hostname   val_1   val_2
    1970-01-15T06:56:07.89Z          us_west   server02   24.5    7
    1970-01-15T06:56:07.890000001Z   us_west   server02   5.24
    

Footnotes:

First created: 2021-04-23 14:02:41
Last updated: 2021-11-15 Mon 10:18
Power by Emacs 27.2 (Org mode 9.4.6)