文档: https://docs.influxdata.com/influxdb/v1.8/
InfluxDB 是一个时间序列数据库,旨在处理高写入和查询负载。它是TICK 堆栈(Telegraf、InfluxDB、Chronograf、Kapacitor)的一个组成部分 。InfluxDB 旨在用作任何涉及大量时间戳数据的用例的后备存储,包括 DevOps 监控、应用程序指标、物联网传感器数据和实时分析。
主要特征
以下是 InfluxDB 当前支持的一些特性,使其成为处理时间序列数据的绝佳选择。
- 专门为时间序列数据编写的自定义高性能数据存储。TSM 引擎允许高速摄取和数据压缩
- 完全用 Go 编写。它编译成没有外部依赖的单个二进制文件(部署简单)。
- 简单、高性能的写入和查询 HTTP API。
- 插件支持其他数据摄取协议,例如 Graphite、collectd 和 OpenTSDB。
- 专为轻松查询聚合数据而设计的富有表现力的类似 SQL 的查询语言(学习成本低)。
- 标签可以索引,以实现快速高效的查询。
- 保留策略有效地自动使陈旧数据过期。
- 连续查询自动计算聚合数据,使频繁查询更高效(对历史数据整合,降低存储成本)。
- 在 InfluxDB 中,您不必预先定义模式
InfluxDB 的开源版本在单个节点上运行。如果您需要高可用性来消除单点故障,请购买企业版或者使用云产品。
基础
字段filed:
- 包括filedkey和fieldvalue,
butterflies = 12 honeybees = 23
。 - filedkey是string。
- filedvalue可以是strings, floats, integers, or Booleans。
标签tag:
相当于索引,加快查询速度。
- 包括tagkey和tagvalue,
location = 1
,scientist = langstroth
桶buket:数据库和保留策略 (database/retention-policy) 的每个组合代表一个存储桶。
连续查询CQ:在数据库中自动并定期运行的 InfluxQL 查询。连续查询在SELECT
子句中需要一个函数,并且必须包含一个GROUP BY time()
子句。
基数:InfluxDB 实例中唯一数据库、度量、标签集和字段键组合的数量。
假设一个 InfluxDB 实例有一个数据库和一个度量。单次测量有两个标签键:email
和status
。如果存在三个不同的email
,并且每个电子邮件地址与两个不同status
的 关联,则测量的系列基数为 6 (3 * 2 = 6)
。
status | |
---|---|
lorr@influxdata.com | start |
lorr@influxdata.com | finish |
marv@influxdata.com | start |
marv@influxdata.com | finish |
cliff@influxdata.com | start |
cliff@influxdata.com | finish |
建议
- 名字避免关键字,不能是time,名字统一小写,不要驼峰。
- 名字不要包含特殊字符,比如\,$,=,,,”等等。
- 各个部门/模块的measurement name有个统一的前缀,方便维护。
- 不要在一个tag里存储多个信息。
- 将常用查询
GROUP BY
元数据存储在标签tag
中。 - 如果你要对其使用InfluxQL函数,则将其放到field中。
- 如果每个数据点包含不同的值,则将数据存储在字段
filed
中。 - 将数值存储为字段(
tagvalue
仅支持字符串值)。 - 当创建的
tag
过多时,写入和读取都可能开始变慢。 - tag的名字和值不要太长,名字和值的长度越长,占用的内存越多。
tagvalue
如果是离散度高的信息(如ID,随机字符串),会导致大量系列,也称作高系列基数,高系列基数是许多数据库工作负载高内存使用的主要驱动因素。因此,为了减少内存消耗,请考虑将高基数值存储在字段值中,而不是标签中。- 相同的 measurement,tagset 和 timestamp 的数据会覆盖。
- tag 数量不要太多,opentsdb 限制为每个点 8 个 tag。每个 tag 可选值也有限制,不能超过 10 万,tag 用于标识点,而不是用于存储数据,如果需要存储数据,应该使用 fields。
- 每一个数据库中的 series 的数量不能超过 100 万。
- field不会被索引,tag会被索引,所以查询时where或者group by从句中以tag为过滤条件查询速度会更快。
- field的类型可以是字符串,浮点,整型,布尔值,tag的类型只能是字符串。
- database names,measurements,tag keys,field keys,和tag values只会存储一次,而field values和timestamps每一个数据点都会存储一次。
- 生成测试数据时将一批数据合并成一个batch,再一次性写入数据库,会比一条一条写入快得多。单个batch官方推荐包含5000-10000条数据。
- influxdb将tag和time作为索引,若插入多条tag和time完全相同的数据,则只会保留最后一次插入的field。
- 系列基数限制为:10k,通常高性能测量的基数非常低,小于 200,但这完全取决于标签数/标签值/点数。
他们和我们强烈建议尽可能使用字段,因为这样可以减轻查询性能的指数损失。
一般查询
语法
SELECT <field_key>[,<field_key>,<tag_key>]
FROM <measurement_name>[,<measurement_name>]
WHERE <conditional_expression> [(AND|OR) <conditional_expression>
-
SELECT "<field_key>","<tag_key>"
返回特定字段和标签。 -
FROM <measurement_name>,<measurement_name>
从多个测量返回数据。 -
where后面的 tag 或者 filed 用双引号,值用单引号,否则会查询不出结果且不报错。
-
tag的key的名称要是全小写,不要驼峰。
SELECT * FROM "h2o_feet" WHERE "level description" = 'below 3 feet' AND time > now() - 1h
- 多个查询条件用
AND
或者OR
连接 - as “alias” 别名
- 不能用于
GROUP BY
对字段进行分组。 GROUP BY <tag_key>,<tag_key>
按多个标签对结果进行分组。
模糊查询
通过正则表达式查询
-- 以【模糊条件】开头的查询方式
SELECT * FROM "tablename" where column =~ /^模糊条件/ limit 1000
-- 以【模糊条件】结尾的查询方式
SELECT * FROM "tablename" where column =~ /模糊条件$/ limit 1000
-- 包含【模糊条件】的查询方式
SELECT * FROM "tablename" where column =~ /模糊条件/ limit 1000
-- 包含多个【模糊条件】的查询方式
SELECT * FROM "tablename" where column =~ /模糊条件1|模糊条件2/ limit 1000
P99
一般P99,P95,P80即可。
- PERCENTILE(field_key,N)
返回field key较大的百分之N的值。即类似于99Line P99。
-- P95
SELECT percentile("hot", 95) FROM "tablename"
-- 如果返回的数字为 6.6 即“hot”列,有 95% 的数据 小于6.6
-
PERCENTILE(/regular_expression/,N)
返回满足正则表达式的每个field key较大的百分之N的值。
-
PERCENTILE(*,N)
返回measurement中每个field key较大的百分之N的值。
- PERCENTILE(field_key,N),tag_key(s),field_key(s)
返回括号里的字段较大的百分之N的值,以及相关联的tag或field,或者两者都有。
N
必须是0到100的整数或者浮点数。
PERCENTILE()
支持所有数值类型的field。
排序
order by
只能对time
进行排序,asc
升序,desc
降序。
Group by
group by
只能对tag keys
和time
分组,group by *
对所有tag keys
分组,不包括time
。用来分组的必须是tag,不支持根据field进行分组。
- group by tag
- group by time(1m)
- group *
示例:
select sum(field) from measurements group by time(1m) ,tag fill(0)
limit slimit
limit后面只能跟上一个数字,表示限定查询的最多条数,点数。
slimit限制每个查询返回的系列数。
N指定每次measurement返回的point个数.
SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] [GROUP_BY_clause] [ORDER_BY_clause] LIMIT <N>
示例:
-- 分组之后,再限定查询条数
select * from table group by "name" limit 1
SELECT "water_level","location" FROM "h2o_feet" LIMIT 3
SELECT MEAN("water_level") FROM "h2o_feet" GROUP BY *,time(12m) LIMIT 2
SELECT_clause [INTO_clause] FROM_clause [WHERE_clause] [GROUP_BY_clause] [ORDER_BY_clause] LIMIT_clause OFFSET <N> [SLIMIT_clause]
- offset来实现分页
- slimit N指定从指定measurement返回的series数
SELECT "water_level" FROM "h2o_feet" GROUP BY * SLIMIT 1
绝对值
- abs()
abs(max(“cost_time”))
变化率
- derivative(), 返回字段的相邻两个点的变化率。默认为1秒(1s)。
示例数据:
name: h2o_feet
time water_level
---- -----------
2015-08-18T00:00:00Z 2.064
2015-08-18T00:06:00Z 2.116
2015-08-18T00:12:00Z 2.028
2015-08-18T00:18:00Z 2.126
2015-08-18T00:24:00Z 2.041
2015-08-18T00:30:00Z 2.051
基础语法
SELECT
DERIVATIVE("water_level")
FROM “h2o_feet”
计算一个字段的变化率
SELECT DERIVATIVE("water_level") FROM "h2o_feet"
name: h2o_feet
time derivative
---- ----------
2015-08-18T00:06:00Z 0.00014444444444444457
2015-08-18T00:12:00Z -0.00024444444444444465
2015-08-18T00:18:00Z 0.0002722222222222218
2015-08-18T00:24:00Z -0.000236111111111111
2015-08-18T00:30:00Z 2.777777777777842e-05
第一个结果0.00014444444444444457是原始数据两个相邻字段值到每秒的变化率。InfluxDB计算字段值的变化,并且转化到每秒:
(2.116 - 2.064) / (360s / 1s)
计算一个字段的变化率并指定时间单位
SELECT DERIVATIVE("water_level",6m) FROM "h2o_feet"
name: h2o_feet
time derivative
---- ----------
2015-08-18T00:06:00Z 0.052000000000000046
2015-08-18T00:12:00Z -0.08800000000000008
2015-08-18T00:18:00Z 0.09799999999999986
2015-08-18T00:24:00Z -0.08499999999999996
2015-08-18T00:30:00Z 0.010000000000000231
第一个结果0.052000000000000046是原始数据两个相邻字段值到每6分钟的变化率。InfluxDB计算字段值的变化,并且转化到每6分钟:
(2.116 - 2.064) / (6m / 6m)
高级语法
SELECT
DERIVATIVE(max("water_level"),6m)
FROM “h2o_feet” GROUP BYtime(6m)
高级语法要求一个GROUP BY time()
子句和一个嵌套的InfluxQL函数。查询首先计算在指定时间区间嵌套函数的结果,然后应用DERIVATIVE()
函数的结果。
SELECT DERIVATIVE(MEAN("water_level")) FROM "h2o_feet" GROUP BY time(12m)
name: h2o_feet
time derivative
---- ----------
2015-08-18T00:12:00Z -0.0129999999999999
2015-08-18T00:24:00Z -0.030999999999999694
SELECT DERIVATIVE(MEAN("water_level"),6m) FROM "h2o_feet" GROUP BY time(12m)
name: h2o_feet
time derivative
---- ----------
2015-08-18T00:12:00Z -0.00649999999999995
2015-08-18T00:24:00Z -0.015499999999999847
non_negative_derivative
返回在一个series中的一个字段中值的变化的非负速率。
InfluxDB计算连续字段值之间的差异和转换的结果为每单位变化率。
单位参数是可选的,如果没有指定,则默认为1秒(1s)。
derivative()和non_negative_derivative所有的查询结果是相同的除了non_negative_derivative()只返回正数。