目录
一、简单介绍
二、相关概念
三、存储引擎 - TSM Tree
四、数据查询与索引结构
五、问题描述
附录
一、简单介绍
InfluxDB 是用Go语言编写的一个用于存储和分析时间序列数据的开源数据库,无需外部依赖。
优点:
- 专为时间序列数据编写的自定义高性能数据存储。 TSM引擎允许高摄取速度和数据压缩
- 完全用 Go 语言编写。 它编译成单个二进制文件,没有外部依赖项
- 简单,高性能的写入和查询HTTP API
- 专为类似SQL的查询语言量身定制,可轻松查询聚合数据
- 标签允许对系列进行索引以实现快速有效的查询
- 保留策略有效地自动使过时数据过期
- 连续查询自动计算聚合数据,以提高频繁查询的效率
缺点:
- 开源版本没有集群功能,集群版本需要收费
存储结构图:
二、相关概念
1>数据格式
虚拟的 key 包括以下几个部分:
- database: 数据库名,在 InfluxDB 中可以创建多个数据库,不同数据库中的数据文件是隔离存放的,存放在磁盘上的不同目录。
- retention policy: 存储策略,用于设置数据保留的时间,每个数据库刚开始会自动创建一个默认的存储策略 autogen,数据保留时间为永久,之后用户可以自己设置,例如保留最近2小时的数据。插入和查询数据时如果不指定存储策略,则使用默认存储策略,且默认存储策略可以修改。InfluxDB 会定期清除过期的数据。
- measurement: 是一个容器,包含了列time,field和tag。对应mysql的table。
- tag sets: 不同的每组tag key和tag value的集合,如location = 1, scientist = langstroth。可索引
- field sets: 每组field key和field value的集合,即我们需要的字段,如butterflies = 3, honeybees = 28。不可索引
- timestamp: 每一条数据都需要指定一个时间戳,这个时间戳以RFC3339格式展示了与特定数据相关联的UTC日期和时间,时间戳视为主键。
- series:series是共同retention policy,measurement和tag set的集合。
数据插入格式
insert into <retention policy> measurement,tagKey=tagValue fieldKey=fieldValue timestampinsert cpu,host=s01,region=hangzhou value=0.64 1520052020000000000
命令说明:
- 插入数据对应的MEASUREMENT名字为cpu;
- 数据tag分别是host和region,field是value;
- 数据的最后一项是时间戳(1520052020000000000),时间戳不是必须的,如果不传则使用influxdb服务端本地时间戳,注意时间戳都是UTC时间tag与tag之间、field与field之间都用逗号分隔
tag与field之间用空格分隔
tag都是string类型,不需要引号将value包裹
field如果是string类型,需要加引号查看tag
show tag keys from cpu;
查看field
show field keys from cpu;
2>Point
InfluxDB 中单条插入语句的数据结构,即一行数据,series + timestamp 可以用于区别一个 point,也就是说一个 point 可以有多个 field name 和 field value。
point是具有相同timestamp、相同series(measurement,rp,tag set相同)的field。这个点在此时刻是唯一存在的。
当你使用与该series中现有点相同的timestamp记将新point写入同一series时,该field set将成为旧field set和新field set的并集。
3>Series
series 相当于是 InfluxDB 中一些数据的集合,在同一个 database 中,retention policy、measurement、tag sets 完全相同的数据同属于一个 series,同一个 series 的数据在物理上会按照时间顺序排列存储在一起。
任意series编号 | retention policy | measurement | tag set |
---|---|---|---|
series 1 | autogen | census | location = 1,scientist = langstroth |
series 2 | autogen | census | location = 2,scientist = langstroth |
4>Shard
shard 在 InfluxDB 中是一个比较重要的概念,它和 retention policy 相关联。每一个存储策略下会存在许多 shard,每一个 shard 存储一个指定时间段内的数据,并且不重复,例如 7点-8点 的数据落入 shard0 中,8点-9点的数据则落入 shard1 中。每一个 shard 都对应一个底层的 tsm 存储引擎,有独立的 cache、wal、tsm file。
如果创建一个新的 retention policy 设置数据的保留时间为 1 天,则单个 shard 所存储数据的时间间隔为 1 小时,超过1个小时的数据会被存放到下一个 shard 中。
三、存储引擎 - TSM Tree
从 LevelDB(LSM Tree),到 BoltDB(mmap B+树),现在InfluxDB使用的是自己实现的 TSM Tree 的算法,类似 LSM Tree,针对 InfluxDB 的使用做了特殊优化
TSM 存储引擎主要由几个部分组成: cache、wal、tsm file、compactor。
1>shard
shard 并不能算是其中的一个组件,因为这是在 tsm 存储引擎之上的一个概念。在 InfluxDB 中按照数据的时间戳所在的范围,会去创建不同的 shard,每一个 shard 都有自己的 cache、wal、tsm file 以及 compactor,这样做的目的就是为了可以通过时间来快速定位到要查询数据的相关资源,加速查询的过程,并且也让之后的批量删除数据的操作变得非常简单且高效。
2>cache
cache 相当于是 LSM Tree 中的 memtable,在内存中是一个简单的 map 结构,这里的 key 为 seriesKey + 分隔符 + filedName,目前代码中的分隔符为 #!~#,entry 相当于是一个按照时间排序的存放实际值的数组。
插入数据时,实际上是同时往 cache 与 wal 中写入数据,可以认为 cache 是 wal 文件中的数据在内存中的缓存。当 InfluxDB启动时,会遍历所有的 wal 文件,重新构造 cache,这样即使系统出现故障,也不会导致数据的丢失。
3>wal
WAL(Write Ahead Log),对数据的修改以日志的形式持久化存储在磁盘上。
wal 文件的内容与内存中的 cache 相同,其作用就是为了持久化数据,当系统崩溃后可以通过 wal 文件恢复还没有写入到 tsm 文件中的数据。
wal 文件中的一条数据,对应的是一个 key(measument + tags + fieldName) 下的所有 value 数据,按照时间排序。
4>tsm file
真实存放数据的文件,单个 tsm file 大小最大为 2GB。每隔一段时间,内存中的时序数据就会执行flush操作将数据写入到文件。
5>compactor
compactor 组件在后台持续运行,每隔 1 秒会检查一次是否有需要压缩合并的数据。
主要进行两种操作,一种是 cache 中的数据大小达到阀值后,进行快照,之后转存到一个新的 tsm 文件中。
另外一种就是合并当前的 tsm 文件,将多个小的 tsm 文件合并成一个,使每一个文件尽量达到单个文件的最大大小,减少文件的数量,并且一些数据的删除操作也是在这个时候完成。
四、数据查询与索引结构
由于 LSM Tree 的原理就是通过将大量的随机写转换为顺序写,从而极大地提升了数据写入的性能,与此同时牺牲了部分读的性能。TSM 存储引擎是基于 LSM Tree 开发的,所以情况类似。通常设计数据库时会采用索引文件的方式(例如 LevelDB 中的 Mainfest 文件) 或者 Bloom filter 来对 LSM Tree 这样的数据结构的读取操作进行优化。
InfluxDB 中采用索引的方式进行优化,主要存在两种类型的索引。
1>元数据索引
一个数据库的元数据索引通过 DatabaseIndex 这个结构体来存储,在数据库启动时,会进行初始化,从所有 shard 下的 tsm file 中加载 index 数据,获取其中所有 Measurement 以及 Series 的信息并缓存到内存中。
2>TSM File 索引
对于 tsm file 中的 Index 部分会在内存中做间接索引,从而可以实现快速检索的目的
五、问题描述
1.influxDB原理和里面几个核心概念
详见上文
2.单机的性能情况
CPU:16 Intel(R) Xeon(R) Silver 4110 CPU @ 2.10GHz
内存:16G
磁盘:4T
MySQL: V5.7
InfluxDB: V1.8.0
单线程插入查询对比(批量插入,每批1万条,查询数据量很少,大约1000条)
原文地址(目前在网上找到的最新测试报告,于今年五月份发布,原文有更多测试报告图):InfluxDB与MySQL的性能测试 - 卷心菜的奇妙历险 - 博客园 (cnblogs.com)
结论:influxdb的插入和查询的速率都远远大于mysql,但它也需要消耗更多内存和CPU。
磁盘数据对比(取自早期17年版本,无新版本相关报告):
mysql:
100万条数据 原始数据: 28.6M 整体磁盘占用: 279MB sql查询方式: 57.59MB 写入速度: 12398/s 读取速度: 37174/s
1000万条数据 原始数据: 286M 整体磁盘占用: 2.4G sql查询方式: 572MB 写入速度: 22988/s 读取速度: 1516/s
3000万条数据 原始数据: 858M 整体磁盘占用: 7.1G sql查询方式: 1714MB 写入速度: 24228/s 读取速度: 2261/s
influxdb:
100万条数据 原始数据: 28.6M 整体磁盘占用:27M 最终磁盘占用: 21M 写入速度: 68521/s 读取速度: 45045/s
1000万条数据 原始数据: 286M 整体磁盘占用:214M 最终磁盘占用: 189M 写入速度: 70165/s 读取速度: 45249/s
3000万条数据 原始数据: 858M 整体磁盘占用:623M 最终磁盘占用: 602M 写入速度: 68318/s 读取速度: 42918/s
整体磁盘占用情况对比
最终磁盘占用情况对比
写入速度对比
读取速度对比
3.容灾策略:数据备份、恢复,如果不能热备至少要有办法做到冷备。
提供tsm文件进行数据持久化,针对这部分数据可完成冷备。
数据写到influxdb时,首先是写入cache和wal文件,默认10分钟||25M 后写入tsm文件。服务重启时,不会立即将wal加载到tsm文件,先加载wal到cache,再从cache写入tsm文件,也遵循写入设定(默认10分钟||25M)。
数据备份与恢复(influxdb默认提供了备份与恢复方式):
//备份指定数据库 (mydb)
>influxd backup -portable -database mydb /data/application/backup//恢复到新的数据库 (mydb_bk)
>influxd restore -portable -db mydb -newdb mydb_bk /data/application/backup//导入到原有数据库 (相当于save,主键为时间戳,不存在则插入,存在则覆盖)
> use mydb_bk
> SELECT * INTO mydb..:MEASUREMENT FROM /.*/ GROUP BY *
> drop database mydb_bk
4.配套的SDK支持情况,需要关注所支持的版本
influxdb最新稳定版本(官方推荐使用):V2.0 最新为:v2.0.7 [2021-06-04]
github地址:https://github.com/influxdata/influxdb-client-java (star: 155)
目前最新java client sdk (目前只支持V2.0版本):
|
sdk(这是以前的SDK,maven上只维护到2020年,支持V2.0以前版本):
|
5.对接的展示层
influxdb作为数据存储
grafana作为数据展示
grafana天生集成influxdb,使用插件集成echart
可选取echart获取页面代码集成grafana,图表难度决定开发时间。
(开发方式详见我的上一篇博客:【Grafana】Grafana集成Echart,基于插件实现自定义数据源+自定义图表_xbl丶的博客-CSDN博客 )
注:上述报告对应influxdb V1 版本,V2版本差距很大,后续研究再补上
附录
github地址:https://github.com/influxdata/influxdb
官方文档:https://docs.influxdata.com/influxdb/v2.0/
influxdb函数:https://docs.influxdata.com/influxdb/v1.8/query_language/functions/#aggregations
企业版:https://docs.influxdata.com/enterprise_influxdb/v1.9/
参考资料:
https://blog.csdn.net/weixin_39630095/article/details/110712861
https://blog.csdn.net/vtnews/article/details/80197045
https://www.cnblogs.com/juanxincai/p/14736218.html