除了最常用的关系数据库和缓存之外,之前我们已经介绍了在 Spring Boot 中如何配置和使用 MongoDB、LDAP 这些存储的案例。接下来,我们继续介绍另一种特殊的数据库:时序数据库 InfluxDB 在 Spring Boot 中的使用。
InfluxDB 简介
什么是时序数据库?全称为时间序列数据库。时间序列数据库主要用于指处理带时间标签(按照时间的顺序变化,即时间序列化)的数据,带时间标签的数据也称为时间序列数据。 时间序列数据主要由电力行业、化工行业等各类型实时监测、检查与分析设备所采集、产生的数据,这些工业数据的典型特点是:产生频率快(每一个监测点一秒钟内可产生多条数据)、严重依赖于采集时间(每一条数据均要求对应唯一的时间)、测点多信息量大(常规的实时监测系统均有成千上万的监测点,监测点每秒钟都产生数据,每天产生几十 GB 的数据量)。虽然关系型数据库也可以存储基于时间序列的数据,但由于存储结构上的劣势,使得这些数据无法高效的实现高频存储和查询统计,因此就诞生了一种专门针对时间序列来做存储和优化的数据库,以满足更高的效率要求。
InfluxDB 就是目前比较流行的开源时序数据库,我们比较常见的使用场景就是一些与时间相关的高频的数据记录和统计需要,比如:监控数据的存储和查询。
在进行下面的动手环节之前,先了解一下 InfluxDB 中的几个重要名词:
- database:数据库
- measurement:类似于关系数据库中的 table(表)
- points:类似于关系数据库中的 row(一行数据)
其中,一个 Point 由三个部分组成:
- time:时间戳
- fields:记录的值
- tags:索引的属性
动手试试
在了解了什么是时序数据库以及 InfluxDB 一些基础概念之后,下面我们通过一个简单的定时上报监控数据的小案例,进一步理解 InfluxDB 的基础配置、数据组织和写入操作!
第一步:创建一个基础的 Spring Boot 项目
第二步:在 pom.xml
中引入 influx 的官方 SDK
<dependency>
<groupId>org.influxdb</groupId>
<artifactId>influxdb-java</artifactId>
</dependency>
注意:这里因为 Spring Boot 2.x 版本的 parent 中有维护 InfluxDB 的 SDK 版本,所以不需要手工指明版本信息。如果使用的 Spring Boot 版本比较老,那么可能会缺少 version 信息,就需要手工写了。
第三步:配置要连接的 influxdb 信息
spring.influx.url=http://localhost:8086
spring.influx.user=admin
spring.influx.password=
三个属性分别代表:连接地址、用户名、密码。到这一步,基础配置就完成了。
注意:虽然没有 spring data 的支持,但 spring boot 2.x 版本中也实现了 InfluxDB 的自动化配置,所以只需要写好配置信息,就可以使用了。具体配置属性可以查看源码:org.springframework.boot.autoconfigure.influx.InfluxDbProperties
。
第四步:创建定时任务,模拟上报数据,并写入 InfluxDB
@Service
@AllArgsConstructor
@Slf4j
public class Monitor {
private InfluxDB influxDB;
@Scheduled(fixedRate = 5000)
public void writeQPS() {
// 模拟要上报的统计数据
int count = (int) (Math.random() * 100);
Point point = Point.measurement("ApiQPS") // ApiQPS表
.tag("url", "/hello") // url字段
.addField("count", count) // 统计数据
.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS) // 时间
.build();
// 往test库写数据
influxDB.write("test", "autogen", point);
log.info("上报统计数据:" + count);
}
}
测试验证
第一步:启动 InfluxDB,并通过命令行准备好要使用的数据库,主要涉及的命令如下;
- 进入 InfluxDB:
$ influx
- 查询当前存在的数据库:
> show databases
- 创建数据库(注意数据库名称与上面 Java 代码中 write 的第一个参数一致):
> create database "test"
第二步:启动 Spring Boot 应用,在定时任务的作用下,我们会看到类似下面的日志:
2021-08-03 01:52:47.732 INFO 94110 --- [ main] c.d.chapter63.Chapter63Application : Started Chapter63Application in 2.326 seconds (JVM running for 3.027)
2021-08-03 01:52:47.764 INFO 94110 --- [ scheduling-1] com.didispace.chapter63.Monitor : 上报统计数据:25
2021-08-03 01:52:52.736 INFO 94110 --- [ scheduling-1] com.didispace.chapter63.Monitor : 上报统计数据:30
2021-08-03 01:52:57.737 INFO 94110 --- [ scheduling-1] com.didispace.chapter63.Monitor : 上报统计数据:38
2021-08-03 01:53:02.739 INFO 94110 --- [ scheduling-1] com.didispace.chapter63.Monitor : 上报统计数据:51
2021-08-03 01:53:07.739 INFO 94110 --- [ scheduling-1] com.didispace.chapter63.Monitor : 上报统计数据:31
第三步:通过命令,查看一下 InfluxDB 中是否已经存在这些数据
> select * from ApiQPS order by time desc;
name: ApiQPS
time count url
---- ----- ---
1627926787730000000 31 /hello
1627926782730000000 51 /hello
1627926777729000000 38 /hello
1627926772727000000 30 /hello
1627926767728000000 25 /hello
可以看到,已经存在与日志中一样的数据了。