欢迎光临
我们一直在努力

Apache IoTDB 数据订阅模块全解析:从核心概念到实战应用

在这里插入图片描述在这里插入图片描述

Apache IoTDB 数据订阅模块全解析:从核心概念到实战应用

Apache IoTDB新版本后推出的数据订阅模块(订阅客户端),参考 Kafka 等消息队列逻辑却不替代它们,专为简单流式数据获取场景提供便捷服务,在持续获取最新数据(比定时查询更实时、编程简单、系统负担小)和简化数据推至第三方系统(无需开发推送组件,可对接 Flink、MySQL 等)场景优势显著。该模块核心概念包括 Topic(数据空间,支持数据入库后创建,有两种输出格式)、两种 Consumer(Pull 和 Push 模式)及 Consumer Group(含多类 Consumer,同组订阅同 Topic 数据不重复处理),支持通过 SQL 语句管理 Topic(创建、删除、查看)与查看订阅状态,也可借助 Java 原生接口使用,不过其在消费有序性(无法保证与写入顺序一致)和消息送达语义(无 Exactly once)上与 Kafka 存在差异。

在这里插入图片描述

在物联网数据处理场景中,实时获取和消费数据是很多开发者绕不开的需求。IoTDB作为专为时序数据设计的数据库,在V1.3.3版本后新增了数据订阅模块(也叫IoTDB订阅客户端),给用户提供了一种和传统数据查询完全不同的流式数据消费方式。

可能有人会问,这个订阅模块是不是要替代Kafka这类消息队列产品啊?其实不是的。它虽然参考了Kafka等产品的基本概念和逻辑,也提供了数据订阅和消费接口,但更多是为了在简单流式获取数据的场景里,让用户能更方便地使用数据订阅服务,没必要用复杂的消息队列产品时,它就能派上大用场。

一、IoTDB订阅客户端的优势场景

在有些应用场景里,用IoTDB订阅客户端消费数据,优势会特别明显,咱们来具体看看: 在这里插入图片描述

1. 持续获取最新数据

要是你需要一直拿到最新的数据,用订阅的方式可比定时查询好多了。首先它更实时,数据一有更新就能获取到;其次应用编程更简单,不用写复杂的定时查询逻辑;最后对系统的负担也更小,不会因为频繁查询占用太多资源。

2. 简化数据推送至第三方系统

以前要把IoTDB里的数据推到第三方系统,可能还得在IoTDB内部开发不同系统的数据推送组件,麻烦得很。但有了订阅客户端就不一样了,直接在第三方系统里实现数据的流式获取就行,不管是推到Flink、Kafka这类大数据组件,还是DataX、Camel这类数据集成工具,甚至是MySQL、PG这类关系型数据库,都方便多了。

二、IoTDB订阅客户端的核心概念

IoTDB订阅客户端有三个核心概念,分别是Topic(主题)、Consumer(消费者)和Consumer Group(消费者组),搞懂这三个概念,就能轻松理解订阅客户端的工作逻辑。

1. Topic(主题)

Topic其实就是IoTDB的数据空间,它是用路径和时间范围来表示的,比如“root.** 的全时间范围”就代表一个Topic。消费者可以订阅这个主题下的数据,不管是当前已经存在的数据,还是未来新写入的数据都能订阅到。

这里得提一下,它和Kafka的Topic还有点不一样。在IoTDB里,就算数据已经入库了,之后再创建Topic也没问题。而且从Topic输出的数据格式还有两种选择,一种是Message格式,另一种是TsFile格式,你可以根据自己的需求选。

2. Consumer(消费者)

Consumer就是IoTDB的订阅客户端,主要负责接收和处理发布到特定Topic的数据,简单说就是从队列里拿数据,然后做相应的处理。

在IoTDB订阅客户端里,有两种不同类型的Consumers,适用的场景也不一样:

  • SubscriptionPullConsumer:它对应的是消息队列里的pull(拉取)消费模式。用这种Consumer的话,用户得自己在代码里主动调用数据获取逻辑,想什么时候拿数据就什么时候调用,灵活性比较高。
  • SubscriptionPushConsumer:它对应的是消息队列里的push(推送)消费模式。这种就不用用户主动调用了,只要有新的数据到达,触发了数据事件,用户的代码就会自动执行来处理数据,实时性更强。

3. Consumer Group(消费者组)

Consumer Group就是一组Consumers的集合,只要是Consumer Group ID相同的消费者,就属于同一个消费者组。关于消费者组,有几个特点你得记清楚:

  • 消费者组和消费者是一对多的关系。一个消费者组里可以有任意多个消费者,但反过来不行,一个消费者不能同时加入多个消费者组。
  • 一个消费者组里,允许有不同类型的Consumer,也就是说SubscriptionPullConsumer和SubscriptionPushConsumer可以在同一个组里。
  • 不用一个消费者组里的所有消费者都订阅同一个Topic,想订阅哪个Topic,消费者自己选就行。
  • 要是同一个Consumer Group里不同的Consumers订阅了相同的Topic,那这个Topic下的每条数据只会被组里的一个Consumer处理,这样就能确保数据不会被重复处理,避免了资源浪费和数据混乱。

三、Topic管理的SQL语句

IoTDB支持用SQL语句对Topic进行创建、删除、查看这些操作,下面就详细说说每个操作怎么用。 在这里插入图片描述

1. 创建Topic

创建Topic的SQL语句格式是这样的:

CREATE TOPIC [IF NOT EXISTS] <topicName>
WITH (
[<parameter> = <value>,],
);

这里面的“IF NOT EXISTS”是干嘛用的呢?其实就是为了防止报错。要是你想创建的Topic不存在,执行这个命令就能创建成功;但要是这个Topic已经存在了,加上“IF NOT EXISTS”就不会报错,要是没加,系统就会提示错误。

接下来咱们看看创建Topic时涉及到的参数,每个参数的必填情况和含义都不一样:

参数是否必填(默认值)参数含义
path optional: root.** 这个参数代表topic对应订阅数据时间序列的路径,简单说就是你想订阅哪一组时间序列的数据,填对应的路径就行。
start-time optional: MIN_VALUE 它表示topic对应订阅数据时间序列的开始时间,这个时间是事件时间(event time)。格式上有几种选择,既可以是ISO格式,比如“2011-12-03T10:15:30”或者“2011-12-03T10:15:30+01:00”,也可以是long类型的裸时间戳,不过单位得和数据库时间戳精度一致。另外还有个特殊值“now”,意思是topic的创建时间。要是start-time设为“now”,而且end-time设为“MAX_VALUE”,那就表示只订阅实时的数据。
end-time optional: MAX_VALUE 它是topic对应订阅数据时间序列的结束时间,同样是事件时间(event time)。格式和start-time一样,支持ISO格式、long类型裸时间戳,也支持“now”这个特殊值。当end-time设为“now”,且start-time设为“MIN_VALUE”时,就表示只订阅历史数据。
processor optional: do-nothing-processor 这个参数是processor插件名以及它的参数配置,作用是对原始订阅数据应用自定义的处理逻辑。你可以像指定pipe processor插件那样来设置它。
format optional: SessionDataSetsHandler 它决定了从这个主题订阅出来的数据呈现形式,目前有两种可选:一种是SessionDataSetsHandler,用这个的话,消费者可以通过SubscriptionSessionDataSetsHandler获取数据,而且能按行消费每条数据;另一种是TsFileHandler,通过SubscriptionTsFileHandler获取数据,消费者可以直接订阅到存储对应数据的TsFile。
mode (v1.3.3.2 及之后版本支持) option: live 这是topic对应的订阅模式,有两个选项。一个是“live”模式,用这种模式订阅主题时,数据集是动态的,能一直消费到最新的数据;另一个是“snapshot”模式,消费者组订阅这个主题的时候,拿到的是订阅时刻(注意不是创建主题的时刻)数据的快照,而且形成订阅后的静态数据集不支持TTL。
loose-range (v1.3.3.2 及之后版本支持) option: “” 这是个字符串类型的参数,用来控制是否严格按照path和time range筛选topic对应的数据。比如填空字符串“”,就表示严格按照path和time range筛选;填“time”,就是不严格按time range筛选(粗筛),但严格按path筛选;填“path”,就是不严格按path筛选(粗筛),但严格按time range筛选;要是填“time, path”“path, time”或者“all”,那就既不严格按path筛选,也不严格按time range筛选(都是粗筛)。

光看参数说明可能有点抽象,咱们来举两个例子,你就明白了:

示例1:全量订阅

要是想全量订阅数据,创建Topic的语句特别简单:

CREATE TOPIC root_all;

这个语句创建了一个叫“root_all”的Topic,因为没指定其他参数,所以会用各个参数的默认值,path默认是“root.**”,时间范围是全时间范围,就能实现全量订阅了。

示例2:自定义订阅

要是你想根据自己的需求,指定path和时间范围来订阅数据,可以这样写:

CREATE TOPIC IF NOT EXISTS db_timerange
WITH (
'path' = 'root.db.**',
'start-time' = '2023-01-01',
'end-time' = '2023-12-31'
);

这个语句首先判断“db_timerange”这个Topic是否存在,要是不存在就创建。订阅的path是“root.db.**”,时间范围是2023年1月1日到2023年12月31日,这样就只会订阅这个路径下、这个时间范围内的数据。

2. 删除Topic

删除Topic有个前提,就是这个Topic没有被订阅,要是正在被订阅,是删不了的。而且一旦Topic被删除,和它相关的消费进度也会被清理掉,所以删除之前得考虑清楚。

删除Topic的SQL语句是:

DROP TOPIC [IF EXISTS] <topicName>;

这里的“IF EXISTS”和创建Topic时的“IF NOT EXISTS”作用类似,都是为了避免报错。要是指定的Topic存在,执行命令就能删除;要是不存在,加上“IF EXISTS”就不会报错,没加的话系统会提示错误。

3. 查看Topic

要是你想知道当前有哪些Topic,或者某个Topic的具体配置,用查看Topic的SQL语句就行。

查看所有Topic的语句:

SHOW TOPICS;

执行这个语句后,会返回所有Topic的信息,结果集里包含“TopicName”(主题ID)和“TopicConfigs”(主题配置)这两项。

查看某个特定Topic的语句:

SHOW TOPIC <topicName>;

把“”换成你想查看的Topic名称,执行后就能看到这个Topic的详细配置,结果集同样包含“TopicName”和“TopicConfigs”。

4. 查看订阅状态

除了管理Topic,有时候你还想知道Topic和消费者组之间的订阅关系,比如某个Topic被哪些消费者组订阅了,某个消费者组里有哪些消费者订阅了某个Topic,这时候就可以用查看订阅状态的SQL语句。

查看所有订阅关系

想知道所有topics和consumer group的订阅关系,用下面这个语句:

SHOW SUBSCRIPTIONS

执行后返回的结果集里有三项:“TopicName”(主题ID)、“ConsumerGroupName”(用户代码中指定的消费者组ID)、“SubscribedConsumers”(该消费者组中订阅了该主题的所有客户端ID)。

查看某个Topic下的所有订阅关系

要是只想看某个特定Topic下的所有订阅关系,可以用这个语句:

SHOW SUBSCRIPTIONS ON <topicName>

把“”换成目标Topic的名称,执行后就能看到这个Topic被哪些消费者组订阅,以及每个消费者组里哪些消费者订阅了它,结果集同样包含“TopicName”“ConsumerGroupName”和“SubscribedConsumers”。

四、API接口:用Java原生接口使用数据订阅功能

除了用SQL语句,IoTDB还支持通过Java原生接口来使用数据订阅功能。要是你习惯用Java开发,这种方式会更贴合你的开发习惯。

不过具体的语法细节比较多,这里就不一一展开说了,你可以去专门的页面查看详细内容,链接是:Java 原生接口(实际使用时,把这里的链接换成真实的官方文档链接即可)。在这个页面里,从如何初始化客户端,到如何创建消费者、订阅Topic、处理数据,都有详细的说明和代码示例,跟着操作就能轻松上手。

五、常见问题:IoTDB数据订阅与Kafka的区别

很多用过Kafka的开发者,在接触IoTDB数据订阅时,都会好奇它和Kafka有啥区别,毕竟两者都能用于数据的订阅和消费。下面就从消费有序性和消息送达语义这两个关键方面,给大家说说它们的不同。

1. 消费有序性

Kafka在消费有序性上有明确的保证,它能保证消息在单个partition(分区)内是有序的。那怎么才能让消费者消费数据的顺序和数据写入的顺序一致呢?只要满足两个条件就行:一是某个topic只对应一个partition,二是只有一个consumer订阅了这个topic,而且这个consumer是单线程的,这样就能保证消费顺序和写入顺序一致。

但IoTDB订阅客户端就不一样了,它没办法保证consumer消费数据的顺序和数据写入的顺序完全一致,不过它会尽量反映数据写入的顺序。所以要是你的业务场景对数据消费顺序要求特别严格,比如不能有任何顺序偏差,那可能Kafka更适合;但要是对顺序要求没那么极端,IoTDB数据订阅也能满足需求。

2. 消息送达语义

消息送达语义也是很多开发者关心的点,毕竟这关系到数据是否会丢失、是否会重复。

Kafka在这方面做得比较好,通过适当的配置,能实现Producer(生产者)和Consumer(消费者)的Exactly once(恰好一次)语义。也就是说,数据只会被生产一次,也只会被消费一次,不会出现重复消费或者消费不到的情况。

而IoTDB订阅客户端目前还没办法提供Consumer的Exactly once语义,这一点在选择使用哪种工具时得考虑进去。要是你的业务场景对消息送达语义要求很高,比如金融交易数据,那可能得优先考虑Kafka;要是对这方面要求没那么高,IoTDB数据订阅的便捷性可能更有吸引力。

总结

IoTDB数据订阅模块作为V1.3.3版本后的新增功能,给用户提供了一种简单便捷的流式数据消费方式,尤其在持续获取最新数据和简化数据推送至第三方系统这两个场景里,优势很明显。

通过本文的介绍,相信大家对它的核心概念(Topic、Consumer、Consumer Group)、Topic管理的SQL语句、Java原生API接口,以及和Kafka的区别都有了清晰的认识。在实际使用时,你可以根据自己的业务场景和需求,选择合适的方式来使用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

✨ 去获取:https://archive.apache.org/dist/iotdb/

联系博主

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

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

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

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


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

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

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

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

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

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


在这里插入图片描述

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

赞(0)
未经允许不得转载:171主机测评 » Apache IoTDB 数据订阅模块全解析:从核心概念到实战应用
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址