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 ...
随机推荐
- python将两个列表组合成元组
point_x = [A_x, B_x, C_x, D_x] point_y = [A_y, B_y, C_y, D_y] points_tulpe = list(zip(point_x, point ...
- 基于Aidlux平台的人脸关键点检测以及换脸算法
第一步:安装APP 手机应用市场下载AidLux 手机和电脑连接同一个Wifi 第二步:配置APP 赋予AidLux各种系统权限,包括:媒体和文件.相机.麦克风.后台弹窗 手机-设置-关于手机-点击操 ...
- 你可得知道物理地址与IP地址
来看看计算机网络中这些常见的概念你有没有理解~ 物理地址 表示方式 物理地址即mac地址,每个网卡都有6字节的唯一标识,前三个字节表示厂商,后三个字节由厂商随机分配. 如何查看 在 command 中 ...
- 【技术积累】Linux中的命令行【理论篇】【六】
as命令 命令介绍 在Linux中,as命令是一个汇编器,用于将汇编语言源代码转换为可执行的目标文件.它是GNU Binutils软件包的一部分,提供了一系列用于处理二进制文件的工具. 命令说明 as ...
- 关于package-lock.json
前言 上篇文章我们了解了package.json,一般与它同时出现的还有一个package-lock.json,这两者又有什么关系呢?下面一起来了解吧. 介绍 package-lock.json 它会 ...
- ATtiny88初体验(一):点灯
ATtiny88初体验(一):点灯 最近逛淘宝时,发现一块ATtiny88核心板(MH-ET LIVE Tiny88)用完红包后只剩4块钱了,果断下单,准备好好把玩一番. MH-ET LIVE Tin ...
- [ABC140E] Second Sum
2023-02-13 题目 题目传送门 翻译 翻译 难度&重要性(1~10):4 题目来源 AtCoder 题目算法 双向链表 解题思路 \(1.\) 当我们用从小到大的顺序来求解时,把原来求 ...
- 【实践篇】DDD脚手架及编码规范
一.背景介绍 我们团队一直在持续推进业务系统的体系化治理工作,在这个过程中我们沉淀了自己的DDD脚手架项目.脚手架项目是体系化治理过程中比较重要的一环,它的作用有两点: (1)可以对新建的项目进行统一 ...
- 2.9 PE结构:重建导入表结构
脱壳修复是指在进行加壳保护后的二进制程序脱壳操作后,由于加壳操作的不同,有些程序的导入表可能会受到影响,导致脱壳后程序无法正常运行.因此,需要进行修复操作,将脱壳前的导入表覆盖到脱壳后的程序中,以使程 ...
- WASI support in Go
原文在这里. 由 Johan Brandhorst-Satzkorn, Julien Fabre, Damian Gryski, Evan Phoenix, and Achille Roussel 发 ...