IoTDB数据订阅API实战:实时消费数据+TsFile订阅全攻略

IoTDB数据订阅API实战:实时消费数据+TsFile订阅全攻略

做IoTDB开发的朋友应该都有实时获取数据库新增数据的需求,不管是大屏实时展示、组态监控,还是定期的TsFile数据备份,IoTDB自带的数据订阅API都能完美满足。这个功能可以让我们通过简单的配置和编码,精准订阅指定测点的新增数据,还支持拉取式消费,适配不同的业务场景。今天就从核心流程、实战代码到全量接口参数,把IoTDB数据订阅API的使用彻底讲清楚,看完就能直接上手开发。

一、数据订阅核心流程

IoTDB的数据订阅功能整体使用起来很简单,核心就四个步骤,按顺序执行就能完成从配置到消费的全流程,记好这个逻辑,开发就不会乱:

  1. 创建Topic:先定义一个Topic,把需要订阅的测点路径配置进去,这是数据订阅的基础;
  2. 订阅Topic:消费者在订阅前,必须确保对应的Topic已经创建,否则订阅会直接失败。而且同一个消费组下的多个消费者,会自动均分该组的订阅数据,做负载均衡;
  3. 消费数据:只有显式订阅了某个Topic,消费者才能收到这个Topic下的新增数据,未订阅的Topic数据完全不会推送;
  4. 取消订阅:当消费者调用close方法关闭时,会自动退出对应的消费组,同时取消该消费者所有的现存订阅,无需手动操作。

二、实战开发步骤

和IoTDB其他Java API一样,数据订阅API也是基于Maven开发,要求JDK≥1.8、Maven≥3.6,下面一步步讲项目搭建和核心代码开发,文中只演示核心流程和接口,想了解全部功能可以参考IoTDB官方的全量接口说明。

2.1 搭建Maven项目,引入依赖

首先创建一个普通的Maven项目,然后在pom.xml中添加IoTDB Session的核心依赖,重点注意:依赖的版本号必须和IoTDB服务端的版本完全一致,否则会出现接口不兼容、连接失败等问题。

xml 复制代码
<dependencies>
    <dependency>
      <groupId>org.apache.iotdb</groupId>
      <artifactId>iotdb-session</artifactId>
      <!-- 版本号与IoTDB服务端版本保持一致 -->
      <version>${project.version}</version>
    </dependency>
</dependencies>

2.2 核心代码案例

IoTDB数据订阅的核心操作分为Topic管理数据消费 两部分,其中数据消费又分实时数据消费 (适配大屏/组态展示)和TsFile文件消费(适配数据备份)两个高频场景,下面分别给出完整可运行的代码案例,直接复制稍作修改就能用。

2.2.1 Topic操作:创建/查询Topic

Topic是数据订阅的载体,所有订阅操作都基于Topic展开,核心操作包括创建Topic、查询所有Topic、查询指定Topic,用SubscriptionSession就能完成所有操作,代码里做了资源自动关闭的处理,避免内存泄漏。

java 复制代码
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import org.apache.iotdb.rpc.IoTDBConnectionException;
import org.apache.iotdb.rpc.StatementExecutionException;
import org.apache.iotdb.rpc.subscription.config.TopicConstant;
import org.apache.iotdb.session.subscription.SubscriptionSession;
import org.apache.iotdb.session.subscription.model.Topic;

public class DataConsumerExample {
    public static void main(String[] args) throws IoTDBConnectionException, StatementExecutionException {
        // 自动关闭Session,无需手动调用close
        try (SubscriptionSession session = new SubscriptionSession("127.0.0.1", 6667, "root", "root", 67108864)) {
            // 1. 打开订阅会话
            session.open();
            
            // 2. 创建Topic,配置订阅的测点路径为root.**(所有测点)
            Properties sessionConfig = new Properties();
            sessionConfig.put(TopicConstant.PATH_KEY, "root.**"); // 核心配置:订阅的测点路径
            session.createTopic("allData", sessionConfig); // Topic名称为allData
            
            // 3. 查询IoTDB中所有已创建的Topic
            Set<Topic> topics = session.getTopics();
            System.out.println("所有Topic信息:" + topics);
            
            // 4. 查询指定名称的Topic(allData)
            Optional<Topic> allDataTopic = session.getTopic("allData");
            System.out.println("指定Topic信息:" + allDataTopic.get());
        }
    }
}
2.2.2 数据消费:两个高频业务场景

IoTDB的数据订阅采用拉取式消费 (Pull Consumer),核心类是SubscriptionPullConsumer,通过配置消费组、消费者ID等参数,实现数据的拉取和消费。下面两个场景是实际开发中最常用的,覆盖了实时监控和数据备份两大需求。

场景1:订阅实时新增数据(大屏/组态展示)

这个场景主要用于实时获取IoTDB中新增的时序数据,比如工业大屏的实时数据展示、设备组态的动态监控,核心是拉取并解析新增的行记录数据。

java 复制代码
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import org.apache.iotdb.rpc.subscription.config.ConsumerConstant;
import org.apache.iotdb.session.subscription.consumer.SubscriptionPullConsumer;
import org.apache.iotdb.session.subscription.payload.SubscriptionMessage;
import org.apache.iotdb.session.subscription.payload.SubscriptionMessageType;
import org.apache.iotdb.session.subscription.payload.SubscriptionSessionDataSet;
import org.apache.tsfile.read.common.RowRecord;

public class DataConsumerExample {
    public static void main(String[] args) throws IOException {
        // 配置消费者参数
        Properties consumerConfig = new Properties();
        consumerConfig.put(ConsumerConstant.CONSUMER_ID_KEY, "c1"); // 消费者ID,自定义
        consumerConfig.put(ConsumerConstant.CONSUMER_GROUP_ID_KEY, "cg1"); // 消费组ID,自定义
        consumerConfig.put(ConsumerConstant.USERNAME_KEY, "root"); // IoTDB用户名
        consumerConfig.put(ConsumerConstant.PASSWORD_KEY, "root"); // IoTDB密码

        // 自动关闭消费者,退出消费组并取消订阅
        try (SubscriptionPullConsumer pullConsumer = new SubscriptionPullConsumer(consumerConfig)) {
            // 1. 打开消费者连接
            pullConsumer.open();
            // 2. 订阅指定Topic(allData,需提前创建)
            pullConsumer.subscribe("allData");

            // 3. 循环拉取数据,实现实时消费
            while (true) {
                // 拉取数据,超时时间10000毫秒(10秒)
                List<SubscriptionMessage> messages = pullConsumer.poll(10000);
                // 遍历拉取到的消息
                for (final SubscriptionMessage message : messages) {
                    final short messageType = message.getMessageType();
                    // 校验消息类型是否合法
                    if (SubscriptionMessageType.isValidatedMessageType(messageType)) {
                        // 解析消息中的数据集,遍历每一条行记录
                        for (final SubscriptionSessionDataSet dataSet : message.getSessionDataSetsHandler()) {
                            while (dataSet.hasNext()) {
                                final RowRecord record = dataSet.next();
                                // 打印实时数据,实际业务中可替换为大屏展示、数据处理等逻辑
                                System.out.println("实时新增数据:" + record);
                            }
                        }
                    }
                }
            }
        }
    }
}
场景2:订阅新增TsFile(定期数据备份)

这个场景主要用于定期备份IoTDB的TsFile文件,需要先创建TsfileHandler类型的Topic,消费时直接拉取并保存TsFile文件到指定目录,实现数据的异地备份、冷备等需求。

前提条件:提前创建TsfileHandler类型的Topic,SQL语句示例:

sql 复制代码
create topic topic_all_tsfile with ('path'='root.**','format'='TsFileHandler')

消费代码案例

java 复制代码
import java.io.IOException;
import java.util.List;
import java.util.Properties;
import org.apache.iotdb.rpc.subscription.config.ConsumerConstant;
import org.apache.iotdb.session.subscription.consumer.SubscriptionPullConsumer;
import org.apache.iotdb.session.subscription.payload.SubscriptionMessage;

public class DataConsumerExample {
    public static void main(String[] args) throws IOException {
        // 配置消费者参数
        Properties consumerConfig = new Properties();
        consumerConfig.put(ConsumerConstant.CONSUMER_ID_KEY, "c1"); // 消费者ID
        consumerConfig.put(ConsumerConstant.CONSUMER_GROUP_ID_KEY, "cg1"); // 消费组ID
        consumerConfig.put(ConsumerConstant.USERNAME_KEY, "root"); // IoTDB用户名
        consumerConfig.put(ConsumerConstant.PASSWORD_KEY, "root"); // IoTDB密码
        consumerConfig.put(ConsumerConstant.FILE_SAVE_DIR_KEY, "/Users/iotdb/Downloads"); // TsFile临时存放目录

        // 自动关闭消费者
        try (SubscriptionPullConsumer pullConsumer = new SubscriptionPullConsumer(consumerConfig)) {
            // 1. 打开消费者连接
            pullConsumer.open();
            // 2. 订阅TsFile类型的Topic(topic_all_tsfile,需提前创建)
            pullConsumer.subscribe("topic_all_tsfile");

            // 3. 循环拉取TsFile文件并保存
            while (true) {
                List<SubscriptionMessage> messages = pullConsumer.poll(10000);
                for (final SubscriptionMessage message : messages) {
                    // 将拉取到的TsFile文件复制到指定目录,重命名为1.tsfile
                    message.getTsFileHandler().copyFile("/Users/iotdb/Downloads/1.tsfile");
                    System.out.println("TsFile文件备份成功!");
                }
            }
        }
    }
}

三、全量接口与参数说明

上面的案例用到的是核心参数和接口,实际开发中会根据业务需求调整更多配置,比如心跳间隔、消费进度提交策略、自动轮询间隔等。下面整理了数据订阅API的核心配置参数核心函数列表,按分类整理,方便开发时查阅。

3.1 核心配置参数

所有消费者的配置都通过Properties对象设置,分为通用参数 (所有消费者都可用)、PushConsumer特殊参数PullConsumer特殊参数,其中我们实际开发中用的最多的是PullConsumer,重点关注即可。

3.1.1 通用参数(SubscriptionConsumer)

适用于所有消费者,包含连接、身份、心跳、文件存储等基础配置:

参数 是否必填(默认值) 参数含义
host 可选(127.0.0.1) IoTDB某DataNode的RPC地址
port 可选(6667) IoTDB某DataNode的RPC端口
node-urls 可选(127.0.0.1:6667) IoTDB所有DataNode的RPC地址列表;host:port和node-urls二选一即可,都填则取并集
username 可选(root) IoTDB的用户名
password 可选(root) IoTDB的密码
groupId 可选(随机分配) 消费组ID,未指定则随机生成,保证全局唯一
consumerId 可选(随机分配) 消费者客户端ID,未指定则随机生成,保证同一消费组内唯一
heartbeatIntervalMs 可选(30000,最小1000) 消费者向DataNode发送心跳的间隔,单位:毫秒
endpointsSyncIntervalMs 可选(120000,最小5000) 消费者探测集群节点扩缩容的间隔,单位:毫秒
fileSaveDir 可选(当前目录/iotdb-subscription) TsFile文件的临时存放目录
fileSaveFsync 可选(false) 订阅TsFile时是否主动调用fsync刷新磁盘
3.1.2 SubscriptionPushConsumer特殊参数

推模式消费者的专属配置,实际开发中使用较少,了解即可:

参数 是否必填(默认值) 参数含义
ackStrategy 可选(AFTER_CONSUME) 消费进度确认策略:BEFORE_CONSUME(收到数据立即提交)、AFTER_CONSUME(消费完成后提交)
consumeListener 可选(无) 消费回调函数,实现ConsumeListener接口定义处理逻辑
autoPollIntervalMs 可选(5000,最小500) 自动拉取数据的间隔,单位:毫秒
autoPollTimeoutMs 可选(10000,最小1000) 每次拉取数据的超时时间,单位:毫秒
3.1.3 SubscriptionPullConsumer特殊参数

拉模式消费者的专属配置,开发中高频使用,重点掌握:

参数 是否必填(默认值) 参数含义
autoCommit 可选(true) 是否自动提交消费进度;设为false则需手动调用commit方法提交
autoCommitInterval 可选(5000,最小500) 自动提交消费进度的间隔,单位:毫秒;仅autoCommit为true时生效

3.2 核心函数列表

按消费者类型分类,整理了开发中常用的函数,包含功能说明和参数,按需调用即可。

3.2.1 SubscriptionPullConsumer(拉模式消费者,高频使用)

核心用于拉取数据、提交消费进度,是实际开发的主力:

函数名 说明 参数
open() 打开消费者连接,启动消费;开启自动提交则启动定时提交线程
close() 关闭消费者连接,退出消费组;开启自动提交则先提交所有未提交进度
poll(final long timeoutMs) 拉取所有订阅Topic的消息,指定超时时间 timeoutMs:超时时间(毫秒)
poll(final Set topicNames, final long timeoutMs) 拉取指定Topic的消息,指定超时时间 topicNames:Topic集合;timeoutMs:超时时间(毫秒)
commitSync(final SubscriptionMessage message) 同步提交单条消息的消费进度 message:要提交的消息对象
commitSync(final Iterable messages) 同步提交多条消息的消费进度 messages:要提交的消息集合
commitAsync(final SubscriptionMessage message) 异步提交单条消息的消费进度 message:要提交的消息对象
commitAsync(final Iterable messages) 异步提交多条消息的消费进度 messages:要提交的消息集合
3.2.2 SubscriptionPushConsumer(推模式消费者,低频使用)

推模式由服务端主动推送数据,开发中使用较少,核心函数如下:

函数名 说明 参数
open() 打开消费者连接,启动自动轮询和消费
close() 关闭消费者连接,停止所有消费操作
ackStrategy(final AckStrategy ackStrategy) 配置消费进度确认策略 ackStrategy:指定的确认策略
consumeListener(final ConsumeListener consumeListener) 配置消费回调逻辑 consumeListener:自定义的消费监听器
autoPollIntervalMs(final long autoPollIntervalMs) 配置自动拉取数据的间隔 autoPollIntervalMs:间隔时间(毫秒)

四、开发注意事项与最佳实践

  1. Topic提前创建:消费者订阅Topic前,必须确保该Topic已经在IoTDB中创建,否则订阅会直接失败,建议将Topic创建放在项目初始化或运维脚本中;
  2. 版本一致性:客户端依赖版本和IoTDB服务端版本必须完全一致,这是IoTDB开发的通用原则,避免出现RPC通信、接口不兼容等问题;
  3. 消费组与消费者设计:同一个消费组下的多个消费者会均分数据,适合高并发消费;不同消费组订阅同一个Topic,各自会收到完整的Topic数据,适合多业务独立消费;
  4. 消费进度提交 :默认开启自动提交消费进度,若业务需要保证Exactly-Once (仅消费一次),建议将autoCommit设为false,在业务处理成功后手动调用commitSync提交进度;
  5. 资源自动关闭 :使用try-with-resources语法包裹SubscriptionSessionSubscriptionPullConsumer,自动关闭资源,避免内存泄漏和连接未释放的问题;
  6. 超时时间设置poll方法的超时时间建议根据业务场景调整,实时监控场景可设置为10秒左右,非实时场景可适当延长;
  7. TsFile订阅注意 :创建TsFile类型的Topic时,必须指定format='TsFileHandler',否则无法拉取到TsFile文件,且需配置好fileSaveDir保证目录有读写权限。

五、总结

IoTDB的数据订阅API是实现实时数据消费TsFile备份 的高效工具,整体采用拉取式设计,灵活性高,适配各种业务场景。核心开发逻辑就是先建Topic,再订阅,最后拉取消费,三步就能完成核心开发,而且API的封装很友好,无需关注底层的通信和负载均衡细节。

本文从核心流程、Maven搭建、两个高频场景的实战代码,到全量的参数和接口说明,再到开发的最佳实践,把数据订阅API的核心内容全部覆盖了。实际开发中,我们主要使用SubscriptionPullConsumer实现拉取式消费,根据业务需求选择是消费实时行记录还是TsFile文件,再配合合理的配置参数,就能实现高效、稳定的数据订阅功能。

不管是工业大屏的实时数据展示,还是设备数据的异地备份,用IoTDB的原生数据订阅API都能轻松实现,相比自己写轮询查询的方式,不仅效率更高,还能避免重复消费、漏消费的问题,是IoTDB实时数据处理的最优选择。

🌐 附:IoTDB的各大版本

📄 Apache IoTDB 是一款工业物联网时序数据库管理系统,采用端边云协同的轻量化架构,支持一体化的物联网时序数据收集、存储、管理与分析 ,具有多协议兼容、超高压缩比、高通量读写、工业级稳定、极简运维等特点。

版本 IoTDB 二进制包 IoTDB 源代码 发布说明
2.0.5 - All-in-one - AINode - SHA512 - ASC - 源代码 - SHA512 - ASC release notes
1.3.5 - All-in-one - AINode - SHA512 - ASC - 源代码 - SHA512 - ASC release notes
0.13.4 - All-in-one - Grafana 连接器 - Grafana 插件 - SHA512 - ASC - 源代码 - SHA512 - ASC release notes

✨ 目前最新版本为2.0.6,去获取:https://archive.apache.org/dist/iotdb/

联系博主

xcLeigh 博主,全栈领域优质创作者,博客专家,目前,活跃在CSDN、微信公众号、小红书、知乎、掘金、快手、思否、微博、51CTO、B站、腾讯云开发者社区、阿里云开发者社区等平台,全网拥有几十万的粉丝,全网统一IP为 xcLeigh。希望通过我的分享,让大家能在喜悦的情况下收获到有用的知识。主要分享编程、开发工具、算法、技术学习心得等内容。很多读者评价他的文章简洁易懂,尤其对于一些复杂的技术话题,他能通过通俗的语言来解释,帮助初学者更好地理解。博客通常也会涉及一些实践经验,项目分享以及解决实际开发中遇到的问题。如果你是开发领域的初学者,或者在学习一些新的编程语言或框架,关注他的文章对你有很大帮助。

亲爱的朋友,无论前路如何漫长与崎岖,都请怀揣梦想的火种,因为在生活的广袤星空中,总有一颗属于你的璀璨星辰在熠熠生辉,静候你抵达。

愿你在这纷繁世间,能时常收获微小而确定的幸福,如春日微风轻拂面庞,所有的疲惫与烦恼都能被温柔以待,内心永远充盈着安宁与慰藉。

至此,文章已至尾声,而您的故事仍在续写,不知您对文中所叙有何独特见解?期待您在心中与我对话,开启思想的新交流。


💞 关注博主 🌀 带你实现畅游前后端!

🏰 大屏可视化 🌀 带你体验酷炫大屏!

💯 神秘个人简介 🌀 带你体验不一样得介绍!

🥇 从零到一学习Python 🌀 带你玩转Python技术流!

🏆 前沿应用深度测评 🌀 前沿AI产品热门应用在线等你来发掘!

💦 :本文撰写于CSDN平台 ,作者:xcLeigh所有权归作者所有)https://xcleigh.blog.csdn.net/,如果相关下载没有跳转,请查看这个地址,相关链接没有跳转,皆是抄袭本文,转载请备注本文原地址。


📣 亲,码字不易,动动小手,欢迎 点赞 ➕ 收藏,如 🈶 问题请留言(或者关注下方公众号,看见后第一时间回复,还有海量编程资料等你来领!),博主看见后一定及时给您答复 💌💌💌

相关推荐
许杰小刀2 小时前
使用 Python 将 Excel 数据批量导入到数据库中(SQLite)
数据库·python·excel
一个天蝎座 白勺 程序猿2 小时前
Apache IoTDB(16):时序数据库的数据删除从单点精准清除到企业级数据生命周期管理
数据库·apache·时序数据库·iotdb
努力进修2 小时前
【MySQL】90% 的 MySQL 性能问题都和它有关!索引的正确打开方式,看完少走 3 年弯路
数据库·mysql
架构师老Y2 小时前
005、数据库选型与ORM技术:SQLAlchemy深度解析
数据库·python
清水白石0082 小时前
Python 在数据栈中的边界:何时高效原型、何时切换到 SQL、Spark、Rust 或数据库原生能力
数据库·python·自动化
dishugj2 小时前
sqlplus / as sysdba登录数据库报错ora-01017解决办法
数据库·oracle
小陈工6 小时前
Python Web开发入门(十七):Vue.js与Python后端集成——让前后端真正“握手言和“
开发语言·前端·javascript·数据库·vue.js·人工智能·python
科技小花10 小时前
数据治理平台架构演进观察:AI原生设计如何重构企业数据管理范式
数据库·重构·架构·数据治理·ai-native·ai原生
一江寒逸10 小时前
零基础从入门到精通MySQL(中篇):进阶篇——吃透多表查询、事务核心与高级特性,搞定复杂业务SQL
数据库·sql·mysql