文章目录
- 1、InfluxDB简介
- 2、InfluxDB数据结构
- 3、InfluxDB存储架构
- 4、InfluxDB基本操作
- 1_数据库操作
- 2_数据表操作
- 3_数据保存策略
- 4_数据查询操作
- 5、存储引擎
- 6、总结
1、InfluxDB简介
时序数据库是近几年一个特殊的概念,与传统的Mysql关系型数据库相比,它的最大的特点是:数据按照时间顺序存储。举例来说,日志数据,是以时间顺序存储的,所以用时序数据库存储是一种很好的选择。使用Mysql在存储的过程中,不对这种基于时间的数据进行优化的,所以在查询、插入上有一些瓶颈。而InfluxDB则会进行优化,并且具备有很多特点,如下:
- 专为时间序列数据编写的自定义高性能数据存储。 TSM引擎允许高摄取速度和数据压缩
- 完全用 Go 语言编写。 它编译成单个二进制文件,没有外部依赖项
- 简单,高性能的写入和查询HTTP API
- 专为类似SQL的查询语言量身定制,可轻松查询聚合数据
- 标签允许对系列进行索引以实现快速有效的查询
- 保留策略有效地自动使过时数据过期
- 连续查询自动计算聚合数据,以提高频繁查询的效率
常见的时间序列数据库除了InfluxDB之外还有:opentsdb、timeScaladb、Druid等。
那么数据是如何在InfluxDB中进行存储的呢?下面我们来看下InfluxDB的数据模型:
2、InfluxDB数据结构
以下是 InfluxDB 和传统关系型数据库(如 MySQL、PostgreSQL)的概念对比表格:
InfluxDB 概念 | 传统关系型数据库概念 | 描述 |
---|---|---|
database | database | 数据库(同) |
Measurement | Table | InfluxDB 中的数据组织单元,是一个容器,类似于关系型数据库中的表。包含了列time,field和tag。 |
Field | Column | InfluxDB 中的数据字段,存储时间序列的具体数据,类似于关系数据库中的列。 |
Timestamp | Timestamp | 每个数据点都有一个时间戳,表示数据的存储时间,关系数据库也可以有时间戳字段。 |
Tag | Index/Metadata | InfluxDB 中的元数据,用于索引和查询,类似于关系数据库中的索引列。 |
Point | Row | 表里面的一行数据,由时间戳(time)、数据(field)和标签(tags)组成 |
Series | Rows | 在 InfluxDB 中,Series 是具有共同retention policy,measurement和tag set的时间序列集合。 |
Continuous Queries | View | InfluxDB 提供的持续查询功能,可以定期计算数据并存储结果,类似于关系型数据库中的视图。 |
Retention Policy | Data Retention | InfluxDB 的数据保留策略,控制数据的存储时间,关系数据库通常没有这种自动过期机制。 |
Line Protocol | SQL | InfluxDB 使用行协议(Line Protocol)写入数据,格式独特;关系型数据库使用 SQL 来管理数据。 |
Schema-less | Schema-based | InfluxDB 是无模式的,数据可以随时添加新字段,而关系型数据库有严格的模式定义。 |
Time Series Data | General Data | InfluxDB 专门为时间序列数据设计,优化高频率写入和查询,而关系数据库更通用,可以存储多种类型的数据。 |
这个表格提供了 InfluxDB 和传统关系型数据库在概念上的主要差异,可以帮助你理解两者的结构和用途。
point属性 | 含义 |
---|---|
time | 数据记录的时间,主索引,默认自动生成,相当于每行数据都具备的列 |
tags | 相当于有索引的列。tag中存储的值的类型总是字符串类型 |
fields | value值,没有索引的列。field中存储的值的类型:字符串、浮点数、整数、布尔型。一个field value总是和一个timestamp相关联 |
Field sets: 每组field key和field value的集合,即我们需要的字段,如internale[key]= 76[value], external[key]= 18[value]。不可索引
Tag sets: 不同的每组tag key和tag value的集合,如device[key]= dev1[value], buiding[key]=b1[value]。可索引
在 InfluxDB 表结构中,field 和 tag 是用于存储数据的两种不同类型。
Field(字段) | Tag(标签) |
---|---|
Field 用于存储实际的数值数据,例如温度、湿度等测量值。 | Tag 用于存储元数据信息和标识数据的键值对,例如传感器名称、地理位置等。 |
Field 是可变的,可以随时间的推移而改变其值。 | Tag 是不可变的,一旦设置就不能更改。 |
Field 的值可以进行聚合计算,例如求平均值或总和等。 | Tag 的值不能进行聚合计算,只能用于过滤和分组查询。 |
Field 不适合用于过滤和索引数据,因为它没有元数据信息。 | Tag 是 InfluxDB 中的主要索引机制之一,可以提高查询性能和数据过滤效率。 |
3、InfluxDB存储架构
在 InfluxDB 中可以创建多个数据库,不同数据库中的数据文件是隔离存放的,存放在磁盘上的不同目录,每个database 可以有多个RP(retention policy数据保存策略),但是只有一个默认策略。策略下按照时间段分为多个ShardGroup,每个ShardGroup存储一个时间段的数据。每个shardgroup下分多个shard来存储数据。如下图所示:
- retention policy: 存储策略,用于设置数据保留的时间,每个数据库刚开始会自动创建一个默认的存储策略 autogen,数据保留时间为永久,之后用户可以自己设置,例如保留最近2小时的数据。插入和查询数据时如果不指定存储策略,则使用默认存储策略,且默认存储策略可以修改。InfluxDB 会定期清除过期的数据。
- ShardGroup: 是一个逻辑概念,按时间区间划分,是InfluxDB数据过期执行的最小单元。
- Shard: 在 InfluxDB 中是一个比较重要的概念,它和 retention policy 相关联。每一个存储策略下会存在许多 shard,每一个 shard 存储一个指定时间段内的数据,并且不重复,例如 7点-8点 的数据落入 shard0 中,8点-9点的数据则落入 shard1 中。每一个 shard 都对应一个底层的 tsm存储引擎.。
4、InfluxDB基本操作
InfluxDB最好基于docker容器进行安装,这里就略过了。
1_数据库操作
首先我们进入虚拟机中的Influx的镜像
docker exec -it influxdb /bin/bash #进入influxdb虚拟机中
链接InfluxDB
influx #进入influx操作界面
显示数据库
show databases #显示数据库
创建数据库
create database restkeeper #创建数据库
删除数据库
drop database restkeeper #删除数据库
使用指定数据库
use 库名称
2_数据表操作
显示所有的表
在InfluxDB当中,并没有表(table)这个概念,取而代之的是MEASUREMENTS,MEASUREMENTS的功能与传统数据库中的表一致,因此我们也可以将MEASUREMENTS称为InfluxDB中的表。
SHOW MEASUREMENTS
新建表
InfluxDB中没有显式的新建表的语句,只能通过insert数据的方式来建立新表。其中 disk_free 就是表名,hostname是索引(tag),value=xx是记录值(field),记录值可以有多个,系统自带追加时间戳
insert customer,customer_name=张三,identity_card=342401198811180000 age=37,earning=5000
insert customer,customer_name=李四,identity_card=342401198811180001 age=37,earning=4500
insert customer,customer_name=王五,identity_card=342401198411180002 age=41,earning=6000
insert customer,customer_name=黄六,identity_card=342401198311180002 age=42,earning=7000
上面,我们新增一条数据,measurement为customer, tag为customer_name,identity_card, field为age,earning。
我们简单小结一下插入的语句写法:
- 基本格式:
insert + measurement + "," + tag=value,tag=value +空格+ field=value,field=value
; - tag与tag之间用逗号分隔;field与field之间用逗号分隔;
- tag与field之间用空格分隔;
- tag都是string类型,不需要引号将value包裹;
- field如果是string类型,需要加引号;
在 InfluxDB 行协议中,一条数据和另一条数据之间使用换行符分隔, 所以一行就是一条数据。另外,在时序数据库领域,一行数据一行数据由下面 4 种元素构成。
删除表
drop measurement customer
3_数据保存策略
InfluxDB是没有提供直接删除数据记录的方法,但是提供数据保存策略,主要用于指定数据保留时间,超过指定时间,就删除这部分数据。
查看保存策略
show retention policies on "db_name"
show retention policies on restkeeper
注意:其中test为数据库名称
创建保存策略
create retention policy "rp_name" on "db_name" duration 3w replication 1 default
create retention policy rp_restkeeper on restkeeper duration 1h replication 1 default
rp_name:策略名; db_name:具体的数据库名;
3w:保存3周,3周之前的数据将被删除,influxdb具有各种事件参数,比如:h(小时),d(天),w(星期);
replication 1:副本个数,一般为1就可以了; default:设置为默认策略
修改保存策略
alter retention policy "rp_name" on "db_name" duration 30d default
alter retention policy rp_restkeeper on restkeeper duration 2h default
删除保存策略
drop retention policy "rp_name" on "db_name"
drop retention policy rp_restkeeper on restkeeper
注意:其中test为数据库名称
4_数据查询操作
InfluxDB基本查询操作和MySQL的基本查询是类似,综合使用如下所示:
#----综合使用
书写顺序
select distinct * from '表名' where '限制条件' group by '分组依据' having '过滤条件' order by limit '展示条数'
执行顺序
from -- 查询
where -- 限制条件 使用单引号,否则无数据返回或报错
group by -- 分组 只能对tags和time进行分组
having -- 过滤条件
order by -- 排序 只能对time进行排序
limit -- 展示条数
distinct -- 去重
select -- 查询的结果
查询数据表customer的所有记录
select * from customer
条件查询
select * from customer where customer_name ='张三'
排序查询
select * from customer order by time desc
去重 (distinct)
select distinct age from customer
注意:distinct 函数只能有一个值
group by
为了分组我们先插入一条数据
insert customer,customer_name=张七,identity_card=342401198311180002 age=42,earning=7000
select * from customer group by identity_card
聚合函数
count()函数:返回一个(field)字段中的非空值的数量。
select count(*) from customer
mean() 函数:返回一个字段(field)中的值的算术平均值(平均值)。字段类型必须是长整型或float64。
select mean(age) from customer
median()函数:从单个字段(field)中的排序值返回中间值(中位数)。中值是在一组数值中居于中间的数值。字段值的类型必须是长整型或float64格式。
select median(age) from customer
spread()函数:返回字段的最小值和最大值之间的差值。数据的类型必须是长整型或float64。
select spread(age) from customer
sum()函数:返回一个字段中的所有值的和。字段的类型必须是长整型或float64。
select sum(age) from customer
integral()函数:用于计算时间序列数据在制定时间范围内的积分值,积分值可以帮助我们更好的理解时间序列数据的趋势和变化
select integral(age) from customer
limit限制条数
select * from customer limit 1 offset 2
or查询
influxDB中没有in的操作,但是有or。对于习惯了mysql的in来说,用or就需要在代码中循环了。
select * from customer where customer_name='张三' or customer_name='李四'
模糊查询
模糊查询支持正则表达式方式,例如
- =~/给定字段/ 包含指定字段的
- =~/^给定字段/ 以指定字段开始的
- =~/给定字段$/ 以指定字段结尾的
select * from customer where customer_name=~/张/
5、存储引擎
InfluxDB 采用自研的TSM (Time-Structured Merge Tree) 作为存储引擎, 其核心思想是通过牺牲掉一些功能来对性能达到极致优化,其官方文档上有项目存储引擎经历了从LevelDB到BlotDB,再到选择自研TSM的过程,整个选择转变的思考。
TSM存储引擎将多个组件结合在一起,并提供用于存储和查询数据的外部接口。 它由许多组件组成,每个组件都起着特定的作用:
- WAL —— WAL是一种写优化的存储格式,允许写入持久化,但不容易查询。 对WAL的写入就是append到固定大小的段中。
- Cache —— Cache是存储在WAL中的数据的内存中的表示。 它在运行时可以被查询,并与TSM文件中存储的数据进行合并。
- TSM Files —— 单个 tsm file 大小最大为 2GB,用于存放数据。TSM file 使用了自己设计的格式,对查询性能以及压缩方面进行了很多优化。
- Compactor —— Compactor负责将不够优化的Cache和TSM数据转换为读取更为优化的格式。 它通过压缩,去除已经删除的数据,优化索引并将较小的文件组合成较大的文件来实现。
存储目录
influxdb的数据存储有三个目录,分别是meta
、wal
、data
:
- meta 用于存储数据库的一些元数据,meta 目录下有一个 meta.db 文件;
- wal 目录存放预写日志文件,以 .wal 结尾;
- data 目录存放实际存储的数据文件,以 .tsm 结尾。
6、总结
另外本篇皆是基于V1版本的InfluxDB,V2还会有一些差别。
主要差别 | 1.x | 2.x |
---|---|---|
存储引擎 | 使用自研的 Time-Structured Merge Tree (TSM) 存储引擎 | 仍然使用 TSM 作为存储引擎,但优化了写入性能和数据压缩。 |
查询语言 | InfluxQL,这是一种 SQL 类的查询语言。 | 引入了 Flux,这是一种功能更强大的查询语言,支持更复杂的数据转换和分析,尤其适合时间序列数据的处理。 |
数据存储 | 使用 measurement、tags 和 fields 的数据模型 | 保持了相似的数据模型,但在功能上更加强大, 支持更复杂的时间序列处理。 新增了 B u c k e t Bucket Bucket的概念,移除了database 和 RP。 一个存储桶(bucket)可以包含多个measurement。 B u c k e t Bucket Bucket是InfluxDB基本存储单元,用于组织和存储时间序列。 是数据的存储容器,区分和隔离不同类型或来源的数据 |
Schema 支持 | 在设计上是无模式的 | 允许更灵活的数据模型,添加了在元数据中支持 Schema 的功能 |
API 变更 | 提供了 REST API 和一些其他功能 | 引入了统一的 API,包括写入、查询、管理和认证等,支持更现代化的 API 设计。 |
客户端库 | 提供了多个语言的客户端库 | 继续支持多种语言的客户端库,并在功能上做了增强,以支持新的 Flux 查询语言。 |
身份验证和授权 | 具有基本的用户管理和身份验证(user,password) | 引入更强大的身份验证机制,改为使用秘钥、令牌身份验证方式。 增加了组织 O r g a n i z a t i o n Organization Organization和原则的概念,用于管理访问权限。 |
用户界面 | no | 提供了新的 Web UI 界面,用户体验更佳,支持直观的数据可视化和管理功能。 |
连续查询 vs Task | 使用连续查询来处理定期计算 | 通过任务(Tasks)和 Flux 语言实现更高级的数据计算和处理。 |
集群管理 | 数据复制以提高可靠性和容错能力 手动介入进行故障转移和节点替换 | InfluxDB 2.x版本简化了集群管理,支持自动故障转移。 |
服务 | 采用单一服务架构,所有功能(写入、查询、管理)都在一个进程中运行。 | 具有更好的微服务架构,支持多种组件,如 InfluxDB、Telegraf、Chronograf 和 Kapacitor 等,更可扩展和可维护。 |
文档 | InfluxDB 1.x 文档 | InfluxDB 2.x 文档 |
Influx官网上有更加详细的说明,比如:官方文档、自研TSM存储引擎的发展过程和选择转变的思考等。
有关使用springboot封装InfluxDB持久层点击这里。