InfluxDB在项目中的实践

简介: InfluxDB在实际项目中的使用步骤以及各种踩坑避雷。

1.业务背景

       项目中有业务数据需要实时读取,并且这些业务数据每秒产生上千条,而InfluxDB对海量的时序数据高性能读写有很好的支持,于是项目中使用InfluxDB支持该业务。先通过MQ订阅的方式将数据实时存储到InfluxDB,前端调用接口实时读取范围时间内的业务数据。


2.InfluxDB版本及依赖

 项目中使用的InfluxDB是2.1.1版本,引入的POM依赖为:

<dependency>

   <groupId>com.influxdb<groupId>

   <artifactId>influxdb-client-java<artifactId>

   <version>3.1.0<version>

<dependency>


3.准备工作

  因为InfluxDB2.0以上不支持SQL语法的连接方式,所以需要使用HTTP API的方式实现数据读写。首先将数据库(每个组织创建时都必须关联一个存储桶(bucket),所以每个组织都至少有一个bucket,bucket是存储时序数据的一个命名空间,相当于数据表)以及API Tokens(用户使用API token访问对应组织的数据)创建完成。


4、单例化InfluxDBClient

  项目开发初期并没有对InfluxDBClient进行单例化,而是每次写数据都会new一个新的client去获取getWriteApi,导致到后期出现大量写操作时造成内存溢出的问题,经过排查是RxNewThreadScheduler这个线程过多导致的。如下图:

1666331418539_11C25156-DB12-4ba9-A761-076AF28152A9.png

然后扒了一下getWriteApi()这个方法的源码,如下图所示:NewThreadScheduler 这个调度器,在真正执行工作的时候,会创建一个NewThreadWorker;当InfluxDB的大量写入数据时,InfluxDB所用的IO线程调度器RxJava,创建的线程池是几乎没有上限的,最终导致内存溢出,所以在使用完writeApi后及时close

1666331938867_260C78BC-4A99-466e-BA5B-79336A00C47F.png

image.png

单例InfluxDBClient 的代码如下:

OkHttpClient.Builder builder = new OkHttpClient.Builder();

       InfluxDBClientOptions build = InfluxDBClientOptions.builder()

               .okHttpClient(builder)

               .url("InfluxDB的连接地址")

               .authenticateToken("生成的API Token".toCharArray())

               .org("组织信息")

               .bucket("组织的存储桶")

               .build();

       InfluxDBClient client = InfluxDBClientFactory.create(build);

      //设置日志打印级别

       client.setLogLevel(LogLevel.BASIC);


5.读写API的使用

5.1.写操作

    最开始设计表结构的时候没有考虑太多,在表的Tag属性填充了数据值,刚开始没什么问题,数据也能正常写入,突然有一天报了max-values-per-tag limit exceeded这样的错误,经过查阅资料才知道在设计表结构的时候就应该考虑清楚,Tag所填充的数据应该是有范围的,是个能穷举完的集合,并且最多只能10万个,否则数据可能会丢失。

   上面的问题优化之后,几天之后又出现了新的问题,看打印的日志写操作特别慢,设置了InfluxDB写操作需要重试3次之后依然无法解决这个问题,后面才发现是填充数据的时候Field字段的Key和Tag有同样的要求,必须是个能穷举完的集合,这个修改好之后发现写操作快了一些,但是依然还是很慢,于是又改了Time这个属性,这个属性不设置的话会默认填充当前时间的时间戳,但是我们业务上是有时间戳这个属性的,我们需要把业务上的时间戳字段填充到Time里面,刚开始填充的是毫秒级别的,换成秒级别的之后,写操作就飞快了,这时InfluxDB的高性能的大量写入时序数据的效果才完美的体现出来。


批量写入数据的代码如下:

    List points = new ArrayList<>();

           list.forEach(data -> {

               Point point = Point

                       .measurement("表名,若数据库不存在该表会自动创建")

                       .time("时间戳", WritePrecision.S)

                       .addTag("属性名", "")

                       .addField("对应的属性值", "");

               points.add(point);

       WriteApi writeApi = client.getWriteApi();

       writeApi.writePoints(points);

       writeApi.close();

5.2.读操作

读数据的代码如下:

       String flux = String.format(

               "from(bucket: \"bucket名称\")\n" +

                       "    |> range(start: "+查询开始时间+" , stop : "+查询结束时间+" )\n" +

                       "    |> filter(fn: (r) => r._measurement == \""+表名+"\"   and r.XXX == \""+属性过滤条件+"\")\n"

       );

       List models = client.getQueryApi().query(flux,XXX.class);


6.其他

当然,InfluxDB的web页面也可以查询数据,如果查询数据时报如图所示的错误时,可以将查询语句中的  |> aggregateWindow(every: v.windowPeriod, fn: mean, createEmpty: false)这一行去掉,就可以正常展示查询结果了。

image.png

image.png

相关文章
|
6月前
|
Prometheus Cloud Native 数据库
Grafana 系列文章(九):开源云原生日志解决方案 Loki 简介
Grafana 系列文章(九):开源云原生日志解决方案 Loki 简介
Foo
|
存储 Prometheus 监控
拥抱开源生态:阿里云InfluxDB集成Prometheus查询
前言 Prometheus是CNCF的毕业项目,其生态已成为云原生监控领域的事实标准。Kubernetes集群的指标通过Prometheus格式暴露,很多新项目也直接选择Prometheus格式暴露指标数据,传统应用(比如MySQL, MongoDB,Redis等)在开源社区都有Prometheus Exporter来接入Prometheus生态。 Prometheus内置的tsdb适合存储短
Foo
2223 0
拥抱开源生态:阿里云InfluxDB集成Prometheus查询
|
存储 数据可视化 搜索推荐
分布式系列教程(26) -分布式日志搜集工具Elasticsearch简介
分布式系列教程(26) -分布式日志搜集工具Elasticsearch简介
109 0
|
6月前
|
存储 监控 物联网
InfluxDB简介与场景
InfluxDB简介与场景
102 1
|
6月前
|
监控 测试技术 时序数据库
软件测试/测试开发|Docker+Jmeter+InfluxDB+Grafana 搭建性能监控平台
软件测试/测试开发|Docker+Jmeter+InfluxDB+Grafana 搭建性能监控平台
|
监控 数据可视化 Go
实战 | Telegraf+ InfluxDB+Grafana 搭建服务器性能监控平台
在之前的文章《移动端UI自动化过程中的难点及应对策略》中我们讨论了影响移动端自动化稳定性的一些因素,其中宿主机环境是一个不可忽视的问题,大家都知道移动端的自动化一般都需要将设备挂载到实体服务器上运行,如果服务器宿主机出现断网或者磁盘空间不足等情况,都会在一定程度上影响自动化任务的执行,因此今天跟大家分享一下如何做服务器宿主机的监控。
474 0
实战 | Telegraf+ InfluxDB+Grafana 搭建服务器性能监控平台
|
Java 关系型数据库 MySQL
后端开发4.Elasticsearch的搭建
后端开发4.Elasticsearch的搭建
68 0
|
时序数据库
|
存储 Prometheus Kubernetes
对比开源丨Prometheus 服务多场景存储压测全解析
作为国内领先的云服务提供商,阿里云提供了优秀的可观测全套解决方案,阿里云 Prometheus 服务正是其中重要一环,相比于开源版本 Prometheus,阿里云的 Prometheus 服务无论是易用性、扩展性、性能均有大幅度提升。
对比开源丨Prometheus 服务多场景存储压测全解析
|
存储 SQL Prometheus
彻底搞懂时序数据库InfluxDB,在SpringBoot整合InfluxDB
之前介绍了运维监控系统Prometheus,然后就有同鞋问我关于时序数据库的情况,所以这里总结一下时序数据库,并以InfluxDB为例,介绍时序数据库的功能特性和使用方式,希望能对大家有所帮助。
12381 4
彻底搞懂时序数据库InfluxDB,在SpringBoot整合InfluxDB