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 ...
随机推荐
- CTF比赛中Web的php伪协议类型题小结
php协议类型 file:// - 访问本地文件系统 http:// - 访问 HTTP(s) 网址 ftp:// - 访问 FTP(s) URLs php:// - 访问各个输入/输出流(I/O s ...
- 【pandas小技巧】--缺失值的列
在实际应用中,数据集中经常会存在缺失值,也就是某些数据项的值并未填充或者填充不完整.缺失值的存在可能会对后续的数据分析和建模产生影响,因此需要进行处理. pandas提供了多种方法来处理缺失值,例如删 ...
- 树莓派烧录系统并在无外接屏幕的情况下连接VNC
上个月老板给了块树莓派3B,开心坏了,在咸鱼上掏了很多零件,花了一段时间做出了一个二驱动的智能小车,但是觉得小车太小,就在又在咸鱼上掏了个四区的地盘,但是在拆卸的过程中,发现树莓派WIFI没有了, ...
- Web通用漏洞--SSRF
Web通用漏洞--SSRF 漏洞简介 SSRF(Server-Side Request Forgery:服务器端请求伪造) 一种由攻击者构造形成由服务端发起请求的一个安全漏洞; 一般情况下,SSRF攻 ...
- 使用MediatR实现CQRS
CQRS和中介者模式 MediatR库主要是为了帮助开发者快速实现两种软件架构模式:CQRS和Mediator.这两种架构模式看上去似乎差不多,但还是有很多区别的. CQRS CQRS是Command ...
- DDD实践:实现基于快照机制的变更追踪
王有志,一个分享硬核Java技术的互金摸鱼侠 加入Java人的提桶跑路群:共同富裕的Java人 去年我们在重构项目中落地了DDD,当时花了点时间研究了下阿里巴巴大淘宝技术发布的<阿里技术专家详解 ...
- 知识图谱(Knowledge Graph)- Neo4j 5.10.0 使用 - Java SpringBoot 操作 Neo4j
上一篇使用了 CQL 实现了太极拳传承谱,这次使用JAVA SpringBoot 实现,只演示获取信息,源码连接在文章最后 三要素 在知识图谱中,通过三元组 <实体 × 关系 × 属性> ...
- 《SQL与数据库基础》21. 分库分表(一)
目录 分库分表(一) 拆分策略 垂直拆分 垂直分库 垂直分表 水平拆分 水平分库 水平分表 技术实现 MyCat概述 概念介绍 环境准备 目录介绍 MyCat入门 配置 分片配置(schema.xml ...
- ATtiny88初体验(五):ADC
ATtiny88初体验(五):ADC ADC模块介绍 ATtiny88单片机包含一个10bit分辨率的ADC模块,拥有8个通道,最大采样率15kSPS,转换时间14us.ATtiny88的ADC参考电 ...
- PHP上传文件$_FILES, $_POST为空 empty 时, 文件上传大小限制
原因 今天在使用ci upload库时, 上传mp4发现表单为空, 上传png等类型却可以正常. 折腾一番后才恍然, PHP上传大小限制的问题. Make一下. 真是失策啊, 一开始我还不相信到处瞎折 ...