Netty采集数据高效写入TDengine

2024-09-03 14:52

本文主要是介绍Netty采集数据高效写入TDengine,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在现代数据处理应用中,高效的数据采集与存储至关重要。Netty 是一个高性能的异步事件驱动的网络应用程序框架,非常适合用于构建高效的数据采集服务。本文将介绍如何使用 Netty 搭建一个数据采集服务,并通过优化的方式将数据高效地写入 TDengine 数据库。

设计思路

我们的目标是构建一个高效的数据采集服务,该服务能够接收来自多个客户端的数据,并在数据量达到一定阈值或经过一定时间后批量写入 TDengine 数据库。为了实现这一目标,我们需要解决以下几个关键问题:

  1. 数据缓冲:需要一个高效的缓存结构来暂存接收到的数据。

  2. 批量处理:当数据量达到一定阈值或经过一定时间后,应将数据批量写入数据库。

  3. 并发控制:确保在多线程环境下数据处理的安全性。

  4. 配置动态调整:允许配置参数如批量大小和最大等待时间的动态调整。

实现过程

1. 数据缓冲

为了高效地暂存数据,我们使用 ConcurrentLinkedQueue 作为数据缓冲区。这种队列是线程安全的,并且提供了高效的插入和删除操作。

private final ConcurrentLinkedQueue<String> buffer = new ConcurrentLinkedQueue<>();

2. 批量处理

当数据达到一定数量或经过一定时间后,我们将启动一个批量插入操作。为了实现这一点,我们使用了两个主要的组件:

  • 计数器:用于跟踪当前缓存中的数据数量。

  • 定时任务:如果数据没有达到阈值,则设置一个定时任务来处理数据。

private final AtomicInteger counter = new AtomicInteger(0);
private ScheduledFuture<?> scheduledFuture = null;

3. 并发控制

为了确保数据处理的安全性,我们使用 ReentrantLock 来保护批量插入操作。此外,我们还使用 AtomicBoolean 来标识当前是否有线程正在进行批量插入操作。

private final ReentrantLock lock = new ReentrantLock();
private final AtomicBoolean isBatchInserting = new AtomicBoolean(false);

4. 配置动态调整

我们使用 Nacos 配置中心来动态调整批量大小和最大等待时间。这样可以在不重启服务的情况下调整这些参数。

@NacosValue(value = "${batchSize:1000}", autoRefreshed = true)
private volatile int batchSize;  // 阈值
​
@NacosValue(value = "${maxWaitTime:500}", autoRefreshed = true)
private volatile long maxWaitTime;  // 最大延迟时间(毫秒)

5. 核心方法

channelRead 方法

每当从客户端接收到一条数据时,都会调用此方法。在此方法中,我们将数据添加到缓冲区,并更新计数器。如果数据达到阈值,则立即执行批量插入。

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {String data = (String) msg;buffer.add(data);int currentCount = counter.incrementAndGet();
​if (currentCount == 1) {scheduleBatchInsert();}
​if (currentCount >= batchSize) {batchInsert();}
}
scheduleBatchInsert 方法

计数器为1的时候,我们会安排一个定时任务来预备处理数据,以保证即便数据条目没有达到设定的阈值,也会被及时批量写入数据库中。

private void scheduleBatchInsert() {scheduledFuture = scheduler.schedule(this::batchInsert, maxWaitTime, TimeUnit.MILLISECONDS);
}
batchInsert 方法

此方法负责实际的批量插入操作。首先,它会检查是否已经有线程正在进行批量插入。如果是,则直接返回。如果不是,则获取锁,并开始处理数据。

private void batchInsert() {if (isBatchInserting.compareAndSet(false, true)) {lock.lock();try {if (counter.get() == 0) {return;}
​List<String> dataToInsert = new ArrayList<>();while (!buffer.isEmpty()) {String data = buffer.poll();if (data != null) {dataToInsert.add(data);}}
​counter.set(0);
​if (scheduledFuture != null && !scheduledFuture.isDone()) {scheduledFuture.cancel(false);}
​if (!dataToInsert.isEmpty()) {try {insertIntoTDengine(dataToInsert);} catch (Exception e) {logger.error("Failed to insert data into TDengine", e);}}} finally {lock.unlock();isBatchInserting.set(false);  // 设置标志位为 false}}
}
insertIntoTDengine 方法

此方法实现了将数据写入 TDengine 的逻辑。具体实现取决于 TDengine 的 API 或者使用的 ORM 框架。

private void insertIntoTDengine(List<String> dataToInsert) {// 实现使用 MyBatisPlus 写入 TDengine 的逻辑,可以参照https://blog.csdn.net/qq_47741012/article/details/141181396
}

6. 生命周期管理

为了确保服务的健壮性,我们需要处理通道关闭和异常捕获事件。此外,还需要提供关闭服务的方法来释放资源。

// 客户端断开连接
@Override
public void channelInactive(ChannelHandlerContext ctx) {cancelScheduledTask();super.channelInactive(ctx);
}
​
Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {logger.error("Exception caught in DataCollectionHandler", cause);ctx.close();
}
​
public void cancelScheduledTask() {if (scheduledFuture != null && !scheduledFuture.isCancelled()) {scheduledFuture.cancel(false);}
}

总结

通过上述设计和实现,我们构建了一个高效的数据采集服务,能够实时接收数据并在数据量达到阈值或经过一定时间后批量写入 TDengine 数据库。这种设计不仅提高了数据处理的效率,还确保了在高并发环境下的数据安全性和一致性。

这篇关于Netty采集数据高效写入TDengine的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133271

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

关于数据埋点,你需要了解这些基本知识

产品汪每天都在和数据打交道,你知道数据来自哪里吗? 移动app端内的用户行为数据大多来自埋点,了解一些埋点知识,能和数据分析师、技术侃大山,参与到前期的数据采集,更重要是让最终的埋点数据能为我所用,否则可怜巴巴等上几个月是常有的事。   埋点类型 根据埋点方式,可以区分为: 手动埋点半自动埋点全自动埋点 秉承“任何事物都有两面性”的道理:自动程度高的,能解决通用统计,便于统一化管理,但个性化定

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

Hadoop集群数据均衡之磁盘间数据均衡

生产环境,由于硬盘空间不足,往往需要增加一块硬盘。刚加载的硬盘没有数据时,可以执行磁盘数据均衡命令。(Hadoop3.x新特性) plan后面带的节点的名字必须是已经存在的,并且是需要均衡的节点。 如果节点不存在,会报如下错误: 如果节点只有一个硬盘的话,不会创建均衡计划: (1)生成均衡计划 hdfs diskbalancer -plan hadoop102 (2)执行均衡计划 hd

高效+灵活,万博智云全球发布AWS无代理跨云容灾方案!

摘要 近日,万博智云推出了基于AWS的无代理跨云容灾解决方案,并与拉丁美洲,中东,亚洲的合作伙伴面向全球开展了联合发布。这一方案以AWS应用环境为基础,将HyperBDR平台的高效、灵活和成本效益优势与无代理功能相结合,为全球企业带来实现了更便捷、经济的数据保护。 一、全球联合发布 9月2日,万博智云CEO Michael Wong在线上平台发布AWS无代理跨云容灾解决方案的阐述视频,介绍了

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

高效录音转文字:2024年四大工具精选!

在快节奏的工作生活中,能够快速将录音转换成文字是一项非常实用的能力。特别是在需要记录会议纪要、讲座内容或者是采访素材的时候,一款优秀的在线录音转文字工具能派上大用场。以下推荐几个好用的录音转文字工具! 365在线转文字 直达链接:https://www.pdf365.cn/ 365在线转文字是一款提供在线录音转文字服务的工具,它以其高效、便捷的特点受到用户的青睐。用户无需下载安装任何软件,只