java把数据批量插入iotdb
package com.xlkh.kafka; import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.session.pool.SessionPool;
import org.apache.iotdb.tsfile.file.metadata.enums.CompressionType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSDataType;
import org.apache.iotdb.tsfile.file.metadata.enums.TSEncoding;
import org.apache.iotdb.tsfile.write.record.Tablet;
import org.apache.iotdb.tsfile.write.schema.MeasurementSchema;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.stereotype.Component; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors; @Slf4j
@Component("com.xlkh.kafka.DataLoaderKafkaConsumer")
public class DataLoaderKafkaConsumer { @Autowired
private SessionPool sessionPool; /**
* 保存已经创建的时间序列
*/
private final static Set<String> STATIC_PATHS = Sets.newConcurrentHashSet(); /**
* fluent_data,批量消费
*/
@KafkaListener(topics = "fluent_data", groupId = "fluent_data_demo", containerFactory = "batchFactory")
@SneakyThrows
public void listenBatchByFluent(List<ConsumerRecord<String, String>> records) {
log.error("从kafka消费fluent数据" + records.size() + "条,当前偏移量:" + records.get(0).offset()); //创建时间序列,如果序列已经存在,不再重新创建
createTimeseriesIfNotExist(records); log.info("开始把数据放到iotdb-----------------------"); insertIotdbByKafka(records); } private void insertIotdbByKafka(List<ConsumerRecord<String, String>> records) throws ParseException, IoTDBConnectionException, StatementExecutionException { //key为kks的路径,value是时间戳集合
Map<String, List<Long>> timeStampMap = new HashMap<>(); //key为kks路径,value是具体的数据
Map<String, List<Float>> values = new HashMap<>(); //保存kks编码
Set<String> kksSet = new HashSet<>(); SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for (ConsumerRecord<String, String> record : records) {
String valueData = record.value();
JSONArray jsonArray = JSON.parseArray(valueData);
for (int i = 0; i < jsonArray.size(); i++) {
Map map = JSON.parseObject(String.valueOf(jsonArray.get(i)), Map.class);
JSONArray jsonArray1 = JSON.parseArray(String.valueOf(map.get("msg")));
for (int j = 0; j < jsonArray1.size(); j++) {
Map map1 = JSON.parseObject(String.valueOf(jsonArray1.get(j)), Map.class);
if (map1.containsKey("big_v")){
String kks = map1.get("kks").toString();
Date date = dateFormat.parse(map1.get("time").toString());
Float val = Float.parseFloat(String.valueOf(map1.get("big_v")));
if(!kksSet.contains(kks)){
timeStampMap.put(kks, new ArrayList<>());
values.put(kks, new ArrayList<>());
kksSet.add(kks);
}
timeStampMap.get(kks).add(date.getTime());
values.get(kks).add(val);
}
}
}
} //遍历批量插入每个设备的数据
for (String kks : kksSet) {
List<Long> longs = timeStampMap.get(kks); //声明Tablet对象设备属性
List<MeasurementSchema> schemas = new ArrayList<>();
schemas.add(new MeasurementSchema(kks,TSDataType.FLOAT));
Tablet tablet = new Tablet("root.param.demo", schemas, longs.size());
for (int row = 0; row < longs.size(); row++) {
int rowIndex = tablet.rowSize++;
//设备时间戳值
tablet.addTimestamp(rowIndex, longs.get(row));
//设置对应的值
tablet.addValue(schemas.get(0).getMeasurementId(), rowIndex, values.get(kks).get(row));
}
//批量插入数据
sessionPool.insertTablet(tablet);
}
log.info("数据成功插入到iotdb-----------------------"+"插入的数据量大小为:"+records.size()); } /**
* 创建时间序列,如果序列已经存在,不再重新创建
*
* @param records 批量数据
*/
private void createTimeseriesIfNotExist(List<ConsumerRecord<String, String>> records) {
try {
List<String> data = records.stream().map(ConsumerRecord::value).collect(Collectors.toList());
HashSet<String> paths = Sets.newHashSetWithExpectedSize(250);
for (String msg : data) { JSONArray jsonArray = JSON.parseArray(msg); for (int i = 0; i <jsonArray.size() ; i++) {
Map map = JSON.parseObject(String.valueOf(jsonArray.get(i)), Map.class);
JSONArray jsonArray1 = JSON.parseArray(String.valueOf(map.get("msg")));
for (int j = 0; j < jsonArray1.size(); j++){
Map map1 = JSON.parseObject(String.valueOf(jsonArray1.get(j)), Map.class);
String kks = map1.get("kks").toString();
String path = "root.param.demo." + kks;
paths.add(path);
}
}
} List<String> notExistPaths = Lists.newArrayList();
List<TSDataType> tsDataTypes = Lists.newArrayList();
List<TSEncoding> tsEncodings = Lists.newArrayList();
List<CompressionType> compressionTypes = Lists.newArrayList();
// List<Map<String, String>> propsList = Lists.newArrayList();
for (String path : paths) {
if (!STATIC_PATHS.contains(path)) {
if (sessionPool.checkTimeseriesExists(path)) {
STATIC_PATHS.add(path);
} else {
notExistPaths.add(path);
tsDataTypes.add(TSDataType.FLOAT);
tsEncodings.add(TSEncoding.RLE);
compressionTypes.add(CompressionType.SNAPPY);
}
}
}
if (CollectionUtil.isNotEmpty(notExistPaths)) {
//批量创建时间序列
sessionPool.createMultiTimeseries(notExistPaths, tsDataTypes, tsEncodings, compressionTypes, null, null, null, null);
//缓存时间序列
STATIC_PATHS.addAll(notExistPaths);
}
} catch (IoTDBConnectionException | StatementExecutionException e) {
log.error(e.getMessage(), e);
}
} }
切记:对于iotdb来说,节点的第一层一直到倒数第二层,都属于设备id,只有最后一层才是你的属性
java把数据批量插入iotdb的更多相关文章
- Java使用iBatis批量插入数据到Oracle数据库
Java使用iBatis批量插入数据到Oracle数据库 因为我们的数据跨库(mysql,oracle),单独取数据的话需要遍历好多遍,所以就想着先从mysql数据库中取出来的数据然后在oracle数 ...
- 多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中【我】
多线程查询数据,将结果存入到redis中,最后批量从redis中取数据批量插入数据库中 package com.xxx.xx.reve.service; import java.util.ArrayL ...
- 使用事务操作SQLite数据批量插入,提高数据批量写入速度,源码讲解
SQLite数据库作为一般单机版软件的数据库,是非常优秀的,我目前单机版的软件产品线基本上全部替换Access作为优选的数据库了,在开发过程中,有时候需要批量写入数据的情况,发现传统的插入数据模式非常 ...
- C#中几种数据库的大数据批量插入
C#语言中对SqlServer.Oracle.SQLite和MySql中的数据批量插入是支持的,不过Oracle需要使用Orace.DataAccess驱动. IProvider里有一个用于实现批量插 ...
- SQL SERVER 使用BULK Insert将txt文件中的数据批量插入表中(1)
1/首先建立数据表 CREATE TABLE BasicMsg( RecvTime FLOAT NOT NULL , --接收时间,不存在时间相同的数据 AA INT NOT NULL, --24位地 ...
- C#:几种数据库的大数据批量插入
在之前只知道SqlServer支持数据批量插入,殊不知道Oracle.SQLite和MySql也是支持的,不过Oracle需要使用Orace.DataAccess驱动,今天就贴出几种数据库的批量插入解 ...
- c#数据批量插入
由于之前面试中经常被问到有关EF的数据批量插入问题,今天以Sqlserver数据库为例,对.net中处理数据批量处理的方案进行了测试对比. 1.四种测试方案 (1)普通的EF数据批量插入:即调用DbS ...
- C#:几种数据库的大数据批量插入(转)
在之前只知道SqlServer支持数据批量插入,殊不知道Oracle.SQLite和MySql也是支持的,不过Oracle需要使用Orace.DataAccess驱动,今天就贴出几种数据库的批量插入解 ...
- C#:几种数据库的大数据批量插入 - faib
在之前只知道SqlServer支持数据批量插入,殊不知道Oracle.SQLite和MySql也是支持的,不过Oracle需要使用Orace.DataAccess驱动,今天就贴出几种数据库的批量插入解 ...
- PHP如何将多维数组中的数据批量插入数据库?
PHP将多维数组中的数据批量插入到数据库中,顾名思义,需要用循环来插入. 1.循环insert into 语句,逐渐查询 <?php /* www.qSyz.net */ @mysql_conn ...
随机推荐
- Redis从入门到放弃(5):事务
1.事务的定义 Redis的事务提供了一种"将多个命令打包, 然后一次性.按顺序地执行"的机制. redis事务的主要作用就是串联多个命令防止别的命令插队. 但是,事务并不具有传统 ...
- 什么是PMP?
PMP(Project Management Professional)中文名称叫项目管理专业人士资格认证.它是由美国项目管理协会(PMI)发起的,严格评估项目管理人员知识技能是否具有高品质的资格认证 ...
- linux基础:编译
程序编译 在linux中,gnu项目提供了gcc编译器.g++编译器和gdb调试器. C和C++语言正在不断发展,为了保持兼容程序语言的最新特性,开发者通常选择GCC来编译C语言编写的源代码,选择G+ ...
- Thinkphp 5.x 远程代码执行漏洞利用小记
Thinkphp 5.x远程代码执行漏洞存在于Thinkphp 5.0版本及5.1版本,通过此漏洞,可以在远程执行任意代码,也可写入webshell 下面是对其进行的漏洞利用! 漏洞利用: 1,利用s ...
- 深入了解Elasticsearch搜索引擎篇:倒排索引、架构设计与优化策略
什么是倒排索引?有什么好处? 倒排索引是一种用于快速检索的数据结构,常用于搜索引擎和数据库中.与传统的正排索引不同,倒排索引是根据关键词来建立索引,而不是根据文档ID. 倒排索引的建立过程如下:首先, ...
- VINS中旋转外参初始化
VINS 中的旋转外参初始化 为了使这个两个传感器融合,我们首先需要做的事情是将两个传感器的数据对齐,除了时间上的对齐,还有空间上的对齐.空间上的对齐通俗的讲就是将一个传感器获取的数据统一到另一个 ...
- 【NestJS系列】核心概念:Middleware中间件
前言 用过express与koa的同学,对中间件这个概念应该非常熟悉了,中间件可以拿到Request.Response对象和next函数. 一般来讲中间件有以下作用: 执行任何代码 对请求与响应拦截并 ...
- ES13 中11个令人惊叹的 JavaScript 新特性
前言 与许多其他编程语言一样,JavaScript 也在不断发展.每年,该语言都会通过新功能变得更加强大,使开发人员能够编写更具表现力和简洁的代码. 小编今天就为大家介绍ES13中添加的最新功能,并查 ...
- 大白话带你认识JVM(转)
转自微信公众号(JavaGuide) 前言 如果在文中用词或者理解方面出现问题,欢迎指出.此文旨在提及而不深究,但会尽量效率地把知识点都抛出来 一.JVM的基本介绍 JVM 是 Java Virtua ...
- 聊聊基于Alink库的决策树模型算法实现
示例代码及相关内容来源于<Alink权威指南(Java版)> 概述 决策树模型再现了人们做决策的过程,该过程由一系列的判断构成,后面的判断基于前面的判断结果,不断缩小范围,最终推出结果. ...