一、InfluxDB使用场景

InfluxDB是一种时序数据库,时序数据库常用于监控场景,比如运维和IOT(物联网)领域,此类数据库旨在存储时序数据和实时计算。

如:将服务器上的CPU的使用情况每隔5秒向InfluxDB中写入一条数据,在图形界面中写一个查询过去每10分钟CPU的平均使用情况,再将该查询开发一个定时任务,每10秒钟执行一次并配置一条规则:查询执行结果 > xxx,就立即触发告警。

上述就是一个监控指标的场景,在IOT领域中也有大量的指标需要监控,比如:机械设备的传感器频率、农田湿度温度等等。

时序数据库相对关系型数据库而言,时序数据库专注的是写入性能,时序数据库不关心事务、不关注更新操作(只写不改)。通常指标数据都是关心最近某段时间的数据,之后的数据基本不会再用。时序数据库的设计特点是冷热差别明显,对最近的数据时序数据库会优先加载到内存中。

二、InfluxDB版本比较和选型

时序数据库一般用于在监控场景,大体上,数据的应用可以分四部分:

  1. 数据采集
  2. 存储
  3. 查询、聚合
  4. 告警

对应InfluxDB 1.x开始也推出了TICK生态全套的解决方案:

  • T:Telegraf 数据采集组件
  • I:InfluxDB 数据存储组件
  • C:Chronograf 用户UI数据管理功能
  • K:Kapacitor 后台处理报警信息

web-1

在InfluxDB 2.x后已经把C、K合并到了I中了,这是两个版本在生态上的差别,在2.x上易用性也随之提高了一个等级:我们只需要安装InfluxDB就得到一个管理UI界面并且附带了定时任务和告警功能。

T是一个单独的插件,专注于收集各种外部中间件的数据写入到InfluxDB中,这个需要单独研究该插件的使用。

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

下面是在web界面中新增Telegraf的配置文件,它已经给支持了非常多的中间件产品,就按照它的示例去给Telegraf机器上设置环境变量和启动即可使用。

image-20230208110411404

image-20230208110114738

2020年InfluxDB推出了2.0版本正式版,底层引擎相差不大,都是基于TSM Tree。但多了一些概念的转变如:db换成了org,新增了bucket。另外查询语言方面优先使用Flux查询语言,使用函数与管道符。Flux语言从1.7版本已经开始提供,但一直在优化和修改,在1.8结束的版本还是优先使用InfluxQL语言操作,在2.0版本开始全面推进Flux语言,一直在优化和改进,目前2.6版本也趋向完整并提供更多的支持中。

目前的InfluxDB只有单节点版本开源,集群版本是需要商业化的购买。并且1.x版本存在安全漏洞,2.x版本已经全面升级了授权功能,所以选2.x版本是当前不二选择。

三、InfluxDB安装

请到官网下载对应的操作系统版本进行安装即可:https://docs.influxdata.com/influxdb/v2.6/get-started/setup/

安装后启动就会暴露8086端口一个web界面,填写用户名登录信息,必须初始化一个组织(Org)和存储桶(Bucket)。Continue后选择quick start即可。

  • Organization:可以理解为数据库(DB)
  • Bucket:可以理解为Schema
  • Retention Policy:时间保存策略即:该Bucket内的数据保存多少天,过期数据自动清理。

image-20230207144707018

image-20230207145201186-1676190631838

第一次只有初始化Bucket默认是该桶数据无过期时间,可以在Bucket界面修改过期时间配置(RP),接下来新增Bucket就出现RP选择框了

image-20230208110854512

四、如何与InfluxDB交互

InfluxDB启动后会想外界提供一套HTTP API,外部程序通过HTTP API即可与InfluxDB进行通信,从2.x开始各种客户端与InfluxDB交互都离不开Api Token。

web-2

下图是UI中新增Api Token界面

image-20230207150027900

Sources里面提供了快速使用各个语言的SDK示例可以参考,File Upload中有几种写入数据的快速方式可以通过UI界面去操作写入。

image-20230207152459600

五、InfluxDB数据行协议

InfluxDB行协议是它独创的一种数据格式,由文本构成,只要符合这种数据格式就能讲数据写入库中。每条数据使用换行符分隔,一行数据有下面4种元素构成。

measurement(度量名称,也可以理解为一张表)

tag sets(标签集,类似mysql的索引)

field sets(字段集)

timestamp(时间戳,必须字段,类似mysql的id字段)

web-3

myMeasurement1,tag1="aaa",tag2="bbb" field1="ccc",field2="ddd" 1675822812745000000
myMeasurement1,tag1="aaa",tag2="bbb" field1="ccc",field2="ddd" ##时间戳可以省略,默认是插入的当前系统时间

myMeasurement2 field1="ccc",field2="ddd" 1675822812745000000 ##如果表名没有逗号分隔默认是没有tag

为什么measurement和tag之间不用空格呢? 请看下图解释

web-console流程图

InfluxDB是个双索引结构,前面的是维度索引,后面的是一个有序的时间索引。

六、时序数据库的数据模型

想要正确使用时序数据库,就必须理解时序数据库的数据管理逻辑。以下我们拿关系型数据库跟时序数据库做个比较。

如下是我们常见的关系型数据库中的数据,其中id、type、time建立了索引列,number非索引列。

| id   | type | time               | number |
| ---- | ---- | ------------------ | ------ |
| 1    | aaa  | 146700702100000000 | 2      |
| 2    | aaa  | 146700702100000000 | 4      |
| 3    | aaa  | 146700702100000000 | 12     |
| 4    | aaa  | 146700702100000000 | 3      |
| 5    | bbb  | 146700702100000000 | 4      |
| 6    | bbb  | 146700702100000000 | 3      |
| 7    | bbb  | 146700702100000000 | 5      |
| 8    | ccc  | 146700702100000000 | 7      |
| 9    | ccc  | 146700702100000000 | 6      |

如下是InfluxDB时序数据库的表示方式。时序数据库有一个序列的概念SERIES,从下面的数据体现来看,Tags是一个Key,Values是一序列的时间内List列表,如果要查询type="aaa"可快速的将这一批数据全部命中,我们如果再指定时间戳的范围,那么查询这些数据会更加的快速。

我们看到关系型数据库一般是以行的数据格式存储。在关系型数据库中查询会是先查询出ID,再把ID内的数据查询出来,这是在查询上的略微差别;另外一点是InfluxDB会将索引上的数据进行范围压缩,让这些数据占用空间尽可能的小。我们看到关系型数据库type的值很多重复的,每一行都出现,而在InfluxDB中就出现一次,再列举出time、number字段,所以InfluxDB体检会更小。

所以InfluxDB中查询出来的这些Values就是序列(Series),它的一行数据叫点(Point),每新增一行就叫Point。我们前面讲到InfluxDB是双索引结构:Tags是索引、Time是索引,那么我们在查询的时候用Tag定位整个序列,再用Time范围过滤我们的Point。

Name: my_test
Tags: type="aaa"
┏━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━━┓  
┃ index ┃               time             ┃    number     ┃   
┣━━━━╋━━━━━━━━━━━━━━━━╋━━━━━━━━┫  
┃      1┃  1675844398225168896.0000000000┃   3.0000000000┃    
┃      2┃  1675845424852518912.0000000000┃   2.0000000000┃    
┃      3┃  1675845484391100928.0000000000┃   4.0000000000┃    
┃      4┃  1675845553342360064.0000000000┃  12.0000000000┃   
┣━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━━┫  
┃                                   3 Columns, 4 Rows, Page 1/1┃
┃                                      Table 1/3, Statement 1/1┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Name: my_test
Tags: type="bbb"
┏━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓  
┃ index ┃               time             ┃    number    ┃  
┣━━━━╋━━━━━━━━━━━━━━━━╋━━━━━━━┫  
┃      1┃  1675844431280630016.0000000000┃  5.0000000000┃   
┃      2┃  1675845484391100928.0000000000┃  3.0000000000┃   
┃      3┃  1675845553342360064.0000000000┃  4.0000000000┃  
┣━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━┫  
┃                                 3 Columns, 3 Rows, Page 1/1┃
┃                                    Table 2/3, Statement 1/1┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Name: my_test
Tags: type="ccc"
┏━━━━┳━━━━━━━━━━━━━━━━┳━━━━━━━┓  
┃ index ┃               time             ┃    number    ┃  
┣━━━━╋━━━━━━━━━━━━━━━━╋━━━━━━━┫  
┃      1┃  1675844431280630016.0000000000┃  6.0000000000┃   
┃      2┃  1675845484391100928.0000000000┃  7.0000000000┃  
┣━━━━┻━━━━━━━━━━━━━━━━┻━━━━━━━┫  
┃                                 3 Columns, 2 Rows, Page 1/1┃
┃                                    Table 3/3, Statement 1/1┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

通过下面的图,我们可以看到measurement、tag_set、field组合成一个序列(series)。每个序列在内存和磁盘上紧密存放,所以当你查询这一序列的数据时,InfluxDB能快速的定位到这一序列的众多数据。你可以将measurement、tag_set、field视为索引,当然了它本身就是。

web-console流程图-1676190791948

七、时间线膨胀

时间线膨胀是所有时序数据库都绕不开的问题,就是我们的时序数据库中的序列太多了,当序列过多的时候写入和读取性通常是断崖式的下降。

避免这类的问题是要注意:每一个tag的值是有限的枚举值,InfluxDB中默认是10万个最大,可调整但不建议调整,反之在生产中要限制在一千个之内。tag索引和关系型数据库不一样,关系型数据库是以唯一性最优。

InfluxDB查询优化步骤:

  1. 优先使用时间范围
  2. 再指定tag值

八、总结

InfluxDB2.x版本更新非常快,目前已经在2.6版本,如何启动和启动参数的变化需要使用者去查看文档,特此强调的是2.x版本没有使用磁盘存储和内存存储参数了,统一是磁盘存储,这也说明了1.x版本在实际使用的调优过程中在2.x版本都已经做了最优的默认。但是2.x的性能其实也没有太多的优化,在大量的数据查询还是非常的慢,超过几千万做个limit都难出结果,大部分查询都是优先用时间作为条件查最近的一小时内的数据居多,也印证了时序数据库的数据存储结构上和关系型数据库的差别。

使用场景不同,数据量不同,在存储数据落盘规范上也要给出响应的指导,如果使用者以关系型数据库的思维去写入数据,那么后期维护就会让人奔溃。

新的查询Flux语言也需要一些学习成本,期待下期再做个文章分享Flux语言的使用。

上一篇 下一篇