本笔记由在Bilibili学习的尚硅谷教学视频后整理得来
文章目录
- 一、InfluxDB基础概念
- 1.1InfluxDB是什么
- 1.2为什么选择InfluxDB而不选择关系型数据库
- 1.3下载安装
- 1.4Promethus数据格式
- 1.5时序数据中的数据模型
- 1.6与时间标准相关的知识
- 二、Flux语言
- 2.1初识Flux语言
- 2.2Flux基本语法
- 三、InfluxDB应用
- 3.1命令行方式写入数据
- 3.2用Telegraf将数据收集到InfluxDB
- 3.3使用node_exporter采集数据到InfluxDB
一、InfluxDB基础概念
1.1InfluxDB是什么
- InfluxDB是一种时序数据库。通常被用于监控场景,比如运维和IOT(物联网)领域。主要解决了存储时序数据并能实时处理它们的需求。
- InfulxDB一般不会修改数据
比如我们想查看服务器CPU的监控情况,结果超过阈值X就触发报警。我们可以每隔10秒向InfluxDB写一条数据,然后写一条查询语句,查询CPU最近30秒的平均使用情况,配置一个报警规则,超过阈值X触发报警。查询语句也每隔10秒执行一次。
对于监控场景,最近的数据是热数据(经常查询的),放在内存中,长期不用的冷数据,会做一些处理(比如压缩等),可以节约磁盘空间。
监控场景,一般都是有固定的步骤
- 采集数据
- 存储数据
- 查询数据
- 监控报警
InfluxDB在1.X版本对应了四个组件
- Telegraf:数据采集
- InfluxDB:数据存储
- Chronograf:数据查询展示
- Kapacitor:后台处理报警信息
Influx在2.X版本,数据存储,查询,监控报警的部分都融入到了InfluxDB
InfluxDB1.X版本使用InfluxQL进行查询,Influx2.X使用FLUX查询语言,可以使用符号和管道符。
1.2为什么选择InfluxDB而不选择关系型数据库
主要考虑因素是写入性能
关系型数据库也能支持时间戳,根据时间戳进行查询。但是关系型一般是基于B+数的数据结构,在数据写入时,有可能会触发叶裂变,产生对磁盘的随机读写,降低写入性能。而时序数据库一般采用LSM Tree的变种,顺序写入磁盘来提高写入性能
专业的人做专业的事
大多数时序数据库虽然写入性能很好,但是不支持事务,不能删除某条数据,大多数时候也不能更新数据
1.3下载安装
一般下载安装采用的方式:
- 直接下载可执行的二进制程序包
- 通过包管理工具安装,比如apt和yum
启动
下载后,直接命令./influxd 启动即可
进入项目
1.4Promethus数据格式
Prometheus 也是一种时序数据库,不过它通常被用在运维场景下。Prometheus 是开放原子基金会的第二个毕业项目,这个基金会的第一个毕业项目就是大名鼎鼎的 k8s。同 InfluxDB 一样,Prometheus 也有自己的数据格式,只要数据符合这种格式就能被
Prometheus 识别并写入数据库。而且 Prometheus 数据格式也是纯文本的。InfluxDB采用的就是Prometheus 数据格式。
(1)measurement(测量名称),类似于关系数据中的Table
(2)Tag Set(标签集)可选,在measurement之后紧接着逗号隔开,相当于一个用来区分measurement的索引,Tag数量太多会减慢插入速度。
(3)Field Set(字段集),实际插入的内容,key为字符类型,Value为浮点数|整数|无符号整数|字符串|布尔值
(4)Timestamp(时间戳),可选,不指定默认当前系统的时间戳
整个数据有两个空格来区分
第一个空格区分measurement,tage和Field Set,第二个空格区分Field Set和Timestamp
1.5时序数据中的数据模型
这里有一个关系数据库中的简单示例
park_id、planet、time 是创建了索引的列, _foodships 是未创建索引的列。
+---------+---------+---------------------+--------------+
| park_id | planet | time | #_foodships |
+---------+---------+---------------------+--------------+
| 1 | Earth | 1429185600000000000 | 0 |
| 1 | Earth | 1429185601000000000 | 3 |
| 1 | Earth | 1429185602000000000 | 15 |
| 1 | Earth | 1429185603000000000 | 15 |
| 2 | Saturn | 1429185600000000000 | 5 |
| 2 | Saturn | 1429185601000000000 | 9 |
| 2 | Saturn | 1429185602000000000 | 10 |
| 2 | Saturn | 1429185603000000000 | 14 |
| 3 | Jupiter | 1429185600000000000 | 20 |
| 3 | Jupiter | 1429185601000000000 | 21 |
| 3 | Jupiter | 1429185602000000000 | 21 |
| 3 | Jupiter | 1429185603000000000 | 20 |
| 4 | Saturn | 1429185600000000000 | 5 |
| 4 | Saturn | 1429185601000000000 | 5 |
| 4 | Saturn | 1429185602000000000 | 6 |
| 4 | Saturn | 1429185603000000000 | 5 |
+---------+---------+---------------------+--------------+
对于的时序数据库
name: foodships
tags: park_id=1, planet=Earth
time #_foodships
---- ------------
2015-04-16T12:00:00Z 0
2015-04-16T12:00:01Z 3
2015-04-16T12:00:02Z 15
2015-04-16T12:00:03Z 15
name: foodships
tags: park_id=2, planet=Saturn
time #_foodships
---- ------------
2015-04-16T12:00:00Z 5
2015-04-16T12:00:01Z 9
2015-04-16T12:00:02Z 10
2015-04-16T12:00:03Z 14
name: foodships
tags: park_id=3, planet=Jupiter
time #_foodships
---- ------------
2015-04-16T12:00:00Z 20
2015-04-16T12:00:01Z 21
2015-04-16T12:00:02Z 21
2015-04-16T12:00:03Z 20
name: foodships
tags: park_id=4, planet=Saturn
time #_foodships
---- ------------
2015-04-16T12:00:00Z 5
2015-04-16T12:00:01Z 5
2015-04-16T12:00:02Z 6
2015-04-16T12:00:03Z 5
对InfluxDB中的对于关系理解:
- InfluxDB中的measurement(foodships)相当于SQL(关系型数据库)中的表
- InfluxDB中的tags(park_id 和 planet),相当于SQL(关系型数据库)中的索引列
- InfluxDB中的fileds(是#_foodships),相当于SQL(关系型数据库)中的未建立索引的列
- InfluxDB 中的数据点(比如,2015-04-16T12:00:00Z 5 )相当于SQL(关系型)数据库中的一行。
对序列的理解:
- 关系型存储数据的数据为一行,而时序数据库存储的数据为1个序列
- 在InfluxDB中,唯一的measurement、tags、fileds组合是一个series(序列)
- 一个序列可以存储相同索引下的多个数据
- 如果我们需求是查询某个设备一段时间内的数据,这个时候对于关系型数据库,需要经过多次寻址找到多个record。而时序数据库,直接通过索引能拿到一个序列的数据。性能是远远强于B+数数据库的。
- 在InfluxDB中,一次性也可以查询多个序列的数据
- 在InfluxDB中,序列的需要在一个可枚举的范围内,因为如果序列过多,则会影响插入和查询性能。
双索引设计
在InfluxDB中,可以把measurement、tags看做索引,还有时间也是索引。在InfluxDB中,一般查询数据的思路:
- 指定要从哪个存储桶查询数据,相当于选择好数据库。
- 通过时间索引缩短要查询的数据范围
- 再通过指定measurement、tags查到要查询的序列
- 然后得到数据
1.6与时间标准相关的知识
GMT(格林威治标准时间)
格林威治(又译格林尼治)它是一个位处英国伦敦的小镇。17 世纪,英国航海事业发展迅速,当时海上航行亟需精确的精度指示,于是英国皇家在格林威治这个地方设立了一个天文台负责测量正确经度的工作。后来 1884 年,在美国华盛顿召开的国际经度会以决定以经过格林尼治天文台(旧址)的经线为本初子午线(0 度经线)。同时这次会以也将全球划分为了 24 个时区。0 度经线所在的时区为 0 时区。现在,有时候你要买一个机械表,如果它说支持 GMT,意思就是支持显示格林威治标
UT(世界时)
1928 年,国际天文联合会提出了 UT 的概念,UT 主要用来衡量一天究竟有多长。一旦一天的长度可以确定,那么将这个长度除以 24 就能确定一小时的长度。以此类推、分钟、秒的长度我们就都能确定了。UT 也是以格林威治时间作为标准的,它规定格林威的子夜为 0 点。在当时,衡量一天长度的方法就是通过天文观测,看地球多久转一圈。但一来天文观测存在误差。二来,地球的自转越来越慢。计时方法亟需革新。
UTC(世界协调时)
UTC,universal Time Coordinated。世界协调时,世界统一时间、国际协调时。它以国际原子时的秒长为基准。但是我们知道,UT 基于天文观测,地球越来越慢那 UT 的秒长应该越来越长。如果不进行干预那么 UTC 和 UT 之间就会有越来也大的误差。
如果这种状况持续下去,在好多好多好多好多年后,人类可能就是 UTC 时间凌晨 3 点起床挤地铁上班了。因此,让 UTC 符合人类生活习惯,就必须控制 UTC 和 UT 的误差大小,于是 UTC 引入了闰秒。所谓闰秒,也就是让在某个时间点上,人为规定这一分钟比普通的分钟多一秒,它有 61 秒。这个时候 1 分 59 秒过了应该接着是 2 分 0 秒,但是在遇到秒时会遇到 1 分 60 秒。
总结
- GMT是最早的国际时间标准,后来是UTC。
- 因为UTC要逼近UT,而UT又以GMT为标准。十分严格地说,UTC和GMT不是一个东西。但宽松地说,你可以把UTC等同于GMT,而且有些网站和应用程序就是这么干的。
- 闰秒之所以存在,源于人类使用的标准时间计量工具原子钟的一天为86400秒,该数字与实际地球自转一天时间并不完全一致,随时间累积,误差就会慢慢增大。为保证我们使用的时间与真实地球自转保持同步,1972年开始,人们引入闰秒。
二、Flux语言
2.1初识Flux语言
Flux 是一种函数式的数据脚本语言,它旨在将查询、处理、分析和操作数据统一为一种语法。可以类比水处理的过程。我们从源头把水抽取出来,然后按照我们的用水需求,在管道上进行一系列的处理修改(去除沉积物,净化)等,最终以消耗品的方式输送到我们的目的地(饮水机、灌溉等)。
InfluxData 公司对 FLUX 语言构想并不是仅仅让它作为 InfluxDB 的特定查询语言,而是希望它像 SQL 一样,成为一种标准。按照这个计划,FLUX 语言应该具备处理来自不同数据源的数据的能力。目前还任重道远。
InfluxDB1.8版本之后才开始兼容Flux语言。而且Flux语言的不同版本的用法不同,高版本也并没有完全兼容低版本的一些功能。所以使用的时候要到官网看准不同InfluxDB对应的不同版本Flux。
https://docs.influxdata.com/flux/v0.x/influxdb-versions/ 这个链接里面有InfluxDB对应的Flux版本。
虽然,FLUX 语言的自我定位一个脚本语言,它也是一个查询语言。一个 FLUX 脚本想要成功执行,它就必须返回一个表流。就像是 SQL 语言想要正确执行,它就必须返回一张表。
2.2Flux基本语法
Flux中只有单行注释,没有多行注释。
FLUX 支持基本的表达式,比如:数字相加或字符串拼接、数字减法、数字相乘、数字除法、取模
import "array"
add=0+1
sub=3-1
str=int(v:"4"+"6")
array.from(rows: [{"value":add},{"value":sub},{"value":str}])
谓词表达式
"John" == "John"
// Returns true
41 < 30
// Returns false
"John" == "John" and 41 < 30
// Returns false
"John" == "John" or 41 < 30
// Returns true
//=~可以判断一个字符串时候能被正则表达式匹配上。
// !~是=~的反操作,判断一个字符串是不是不能被某个正则表达式匹配。
"abcdefg" =~ "abc|bcd"
// Returns true
"abcdefg" !~ "abc|bcd"
// Returns false
控制语句
Flux没有if else,for while,try catch等语法。有一个和三目表达式比较像的
三目表达式可以嵌套
import "array"
x=1
a= if x==0 then "zs" else "ls"
b= if x==0 then "zs" else if x==2 then "ls" else "ww"
array.from(rows: [{"value":a},{"value":b}])
三、InfluxDB应用
3.1命令行方式写入数据
进入InfluxDB后,首先需要配置一个Buckets,类似数据库。
写一个案例,向InfulxDB插入一条数据。并且能查看。
先创建一个BUCKET
配置名字,以及是否要定期删除数据。坐标NEVER代表数据永久保留,右边可以选择数据定期删除
创建后可以添加数据
这里选择命令行方式插入数据
这是另外一个入口
命令行写入数据
zyp,name=zhangsan age=10 1668834398000
zyp,name=zhangsan age=20 1668834399000
zyp,name=lisi age=15 1668834399000
数据可在视图中查看
3.2用Telegraf将数据收集到InfluxDB
在InfluxDB上配置Telegraf,主要是配置Telegraf的配置文件,然后暴露一个URL给Telegraf启动时进行访问
1.首先建一个Bucket便于测试
2.在InfluxDB中创建并配置Telegraf的配置文件
3.这里选择监控虚拟机系统的cpu,磁盘等
这里就是InfluxDB配置好的Telegraf配置文件,告诉了需要去安装Telegraf,然后配置Token后进行连接访问
4.安装Telegraf后,配置连接InfluxDB的环境Token
5.启动telegraf
6.在InfulxDB中查看telegraf收集到的虚拟机cpu,磁盘等情况
3.3使用node_exporter采集数据到InfluxDB
在Prometheus的架构设计中,Prometheus Server并不直接服务监控特定的目标,其主要任务负责数据的收集,存储并且对外提供数据查询支持。因此为了能够能够监控到某些东西,如主机的CPU使用率,我们需要使用到Exporter采集数据,这里node_exporter就是采集数据的作用。
1.安装并启动node_exporter
2.node_exporter收集的数据
3.InfluxDB中配置展示node_exporter收集的数据
3.InfluxDB中查看node_exporter收集的数据