在 4 月中旬的 SeaTunnel&TDengine 联结 Meetup 上,来自 北京沃东天骏信息技 ason 术有限公司的架构师 李宏宇,为大家带来了《应用 SeaTunnel 搞定 TDengine 数据同步》,通过 TDengine-Connector 解析与应用示例介绍了 SeaTunnel 与实时数据库 TDengine 同步集成的过程。演讲内容整顿如下:
大家好,我叫李宏宇,目前次要关注的方向是数据仓库,包含构建、集成、开发,以及利用端,目前次要聚焦的一个更细分实时数仓畛域。明天跟大家分享的一个主题是咱们怎么样应用 SeaTunnel 这样一个数据集成和同步引擎,实现实时数据库 TDengine 数据的导入导出,以及同步集成的过程。
本次分享大略分为以下几个局部:
● SeaTunnel 基本概念介绍
● TDengine Connector 性能个性
● TDengine Connector 读取解析
● TDengine Connector 写入解析
● TDengine Connector 应用示例
● 如何参加奉献
SeaTunnel 基本概念介绍
1 SeaTunnel 示例
解说 SeaTunnel 的基本概念,我感觉最好的形式办法就是把 SeaTunnel 应用的示例给大家间接展现进去,很多对于 SeaTunnel 的基本概念和重要概念都能够通过示例都能够引出来。
SeaTunnel 是一个什么样的引擎?它是一个国产的数据同步集成框架和引擎。目前,是 SeaTunnel 在 ASF 孵化器中处于孵化阶段。我集体认为 SeaTunnel 引擎最大的亮点和不便之处体现在它把整个数据集成这个畛域中的过程和逻辑的定义全副压缩到了 DSL 配置文件里,通过简略、清晰明了的配置文件,能够把整个数据集成的过程形容得很分明,并且把整个集成过程中可能会遇到的各种细节问题都做了封装,有了它,能够大幅度地简化数据集成的难度。
上图展现了一个最根本的简略的数据集成,在 SeaTunnel 配置 1 个示例大略分成 4 个局部,env 次要是用于配置数据集成工作的环境信息,比方并行度、工作的执行模式等。其余三个包含 Source、Transform 和 Sink,别离对应数据从一个指标,通过一个转换过程,输入到另一个指标,所以,这 4 个局部就把整个数据集成的过程形容得很清晰。
上图示意把配置文件保留好之后,丢到 SeaTunnel 引擎下来执行,就能够失去对应的执行后果。
当咱们对 SeaTunnel 有了一个整体的意识之后,来看一下它到底是怎么来实现的数据同步的过程。
2 SeaTunnel 整体架构
在此之前咱们须要理解一下 SeaTunnel 的整体架构,它总体上大略分成三个档次,别离对应的是下面的 API connectors 的 API 层,两头的 Translation 翻译层,以及最上面的引擎层,即理论中跑数据的这一层。
Connector API 这一层的次要工作,是把不同的数据终端,包含 Hadoop,TDengine 等各种不同的数据源的接入的逻辑全副做一个公共的形象,以便于适配不同的数据源。
其中包含 4 个小的组成构件,别离是 Source、Sink,别离对应数据源输出和数据输入的行为模式。Data type,即具体到数据类型,不同的数据终端和不同的数据类型,怎么和引擎做桥接的构建。以及工作容错机制,对应了 state 状态存储。所以,这 4 个局部加在一起就定义好了 1 个 connector 的根本行为模式。
定义好了这些组件的行为之后,咱们会通过两头 Translation 这一层把它翻译为上面的引擎层里具体能够执行的代码和逻辑,这样就实现了不同的 connector 到不同引擎的适配过程,所以 Translation 层次要是实现了适配,是一个 adapter。
具体到引擎层,目前咱们反对 Spark、Flink 和 SeaTunnel Zeta 引擎。SeaTunnel Zeta 是社区本人研发的一款轻量级的,专门应答数据同步场景的数据同步引擎,是能够屏蔽掉 Spark 和 Fink 的。
对于 SeaTunnel Zeta 更具体的信息,可参考文章理解:https://www.bilibili.com/read/cv20989971
3 SeaTunnel Connector 简介
接下来介绍 SeaTunnel connector 的开发模式和开发特点。
Connector 次要由两个局部,Source 和 Sink 组成,别离对应了数据的读取过程和数据的写出过程。这两个组件两头,有一个数据的形象层,把数据抽象成 SeaTunnelRow 抽象类,用于承载理论数据传输过程中的载体。
在此须要特地提到,除了数据自身以外,咱们目前有一些元数据的传输过程也是在 SeaTunnelRow 上的,所以数据自身和元数据都是通过这样的形象层实现传输。
所以有了 Zeta,Source、形象层和 Sink,咱们就能够在不同的数据源和数据终端之间做数据的迁徙和搬运。这就是 connector 的根本状况。
4 SeaTunnel Connector 生态
SeaTunnel Connect 目前曾经接入比拟罕用的 100 多个数据终端,待接入和进行中的大略有 300 多个。
目前 SeaTunnel Connector 接入详情见链接:
https://seatunnel.incubator.apache.org/docs/2.3.1/Connector-v…
https://github.com/apache/incubator-seatunnel/issues/3018
如果有间接在线上做部署的想法,大家能够参考链接详细信息,踊跃奉献社区。
TDengine Connector 性能个性
接下来来看 TDengine Connector 的具体情况。
1TDengine 重要概念阐明
以 TDengine 为例,这里须要先阐明两个对于 TDengine 的基本概念,不便大家了解。
TDengine 是一款国产时序数据库,数据按工夫先后顺序存储和检索。所谓时序数据库,就是字面了解,按工夫程序把数据进行存顺序存储和检索的这样一款数据库。
它次要面对的场景包含物联网畛域的数据,其中两个与数据同步相干的概念,一个叫 Super Table,也叫 STable,就是超级表,一个叫 Subtable 子表,这两个表之间是什么关系呢?
你能够了解为就是 Super Table 是对于雷同数据类型的一类数据采集点的形象,比方电表就能够作为一个 Super Table,具体到某一户的某一块电表,作为一条具体的数据,具体的数据采集量存储在 Subtable 外面。
另外,Super Table 次要实现的是 schema 定义,Subtable 是应用 Schema 去实现具体的数据存储。Super Table 次要面向的应用场景是用户操作 Super Table,Subtable 更多的是一个外部的构造,一般来讲是不让用户间接进行操作。能够类比为咱们面向对象的概念外面的 class 和 object 这样的概念,所以它们两个之间的对应关系也就是一对 n 的对应关系。
这外面有着 TDengine 比拟独特的一个设计理念,就是一个设施一张 Subtable。在前面的数据同步的时候,跟这个理念设计是有一些关系的,所以在这简略跟大家提一下。
2 Source 性能个性
再具体说一下 SeaTunnel TDengine Source 这一端,当初曾经具备了哪些性能个性,实现形式,以及利用场景。
TDengine Source,即读取端当初反对批量读取。具体实现形式其实很简略,就是通过拜访 stable,而不是具体到某一个 Subtable,通过 SCO,因为 SP 下辖了很多 subtable 指标,所以就对 SCO 的定义和拜访,就能够批量获取到所有设施 ID 的继续数据。留神,子表名其实就是设施 ID,这个设施 ID 在用户间接拜访超级表时是无奈间接拜访到的,因为它是绝对比拟暗藏的一层。然而在 Sink 端,咱们在输入数据的时候须要这部分数据,所以,目前表名子表 ID 我把它放在了 SeaTunnelRow 的第一位,还携带了元数据,方才咱们也有提到这种设计。
流式数据的读取,目前还没有接入,这块是咱们下一步要接入的一个方向。计划是引入 TDengine subscription 个性。
字段投影,字段映射,咱们能够在配置中的 Transform 选取若干字段做同步,或者进行字段重命名。
数据类型映射,TDengine 所有的数据类型目前是都反对的。
并行读取,大家次要做的是分片,而后并行多线程地去读数据。TDengine 里的设计是依照 subtable,就是按子表去切分数据分片,而不是像其余的一些数据引擎时序数据引擎那样依照工夫去切分片。
为什么这样设计?这就与咱们方才提到一个设施一张表的设计理念无关。TDengine 示意,这是因为在数据集成同步的场景下,按表同步,而不是把表切分后再依照工夫做切分,性能会更高。因而,按工夫同步因为波及到地点认证自身的数据存储模式和其余的数据理论数据引擎的一个设计上的不同,所以这块也做了一些取舍。
对于容错的,就是状态复原,包含至多一次至少一次刚好一次的语义,目前实现的是至多一次,具体的工夫逻辑还要具体跟大家探讨。
3 Sink 性能个性
Sink 端是 c 端在接入数据当前,把数据写入到对应的 TDengine 实例,波及元数据的辨认过程。
目前,数据是分具体的指标以及指标对应的 title,咱们叫标签,字段的辨认是主动的,咱们的 connector 本人去实现,不须要用户配置。辨认完了之后,取出对应的字段,就能够实现一个插入操作了。
数据类型映射和 Source 一样,是全副都反对的。
批量提交和异样重试,受限于咱们当初应用的 HTTP 的 restful 格调的 driver,导致这两个目前还没有实现,但后续会追加上。
对应的容错机制也是至多一次的保障。
这里特地提一下,在时域数据库里工夫、time、stamp、字段是绝对比拟重要的,所有的数据都是跟着 stamp 走的,所以在数据跨时区导入导出的时候,可能会波及到时区的变更,所以这块也专门提供了市时区指定的性能。
TDengine Connector 读取解析
上面我别离解读一下 TDengine Connector 读取和写入的功能模块实现形式及性能个性。
1 字段类型映射
对于读取这一部分,目前所有 TDengine 的数据类型都是能够残缺映射到 SeaTunnel 数据类型的。
然而这外面有一个特例,就是 Json。目前咱们把 Json 当成了一个 string 进行传输和导入导出。如果后续有具体的场景和需要,须要 Json 独自和 SQL 离开解决,咱们能够再做进一步迭代。
2 批量读取
对于批量读取,因为 TDengine 自身的设计特点,所有的批量数据的读取是针对超级表的操作,而超级表的操作是在 Source 端。咱们在实现逻辑的时候,实际上是把超级表的同步过程翻译为了若干的子表的同步过程,由子表的每一张子表对应一个不同的分片,就能够把批量同步数据,而不是对工夫分片做更细的分片。
这张图能够清晰地展现批量读取的过程。
3 并行读取:切分 Split,调配 Reader
上图展现了不同的技术组件,在不同的档次上起到的不同作用,以及不同的组件外面概念之间一对一,和一对多的对应关系。
首先,咱们要同步的数据源就是 TDengine,要同步的是某一张 stable,就是 super table,supertable 上面一对多地映射了多张 subtable,咱们在理论导入导出的时候,实际上是把不同的子表映射到 SeaTunnel 分片下来,SeaTunnel 分片再通过哈希形式把它们调配给不同的 reader。不同的 Reader 再对应到不同的引擎底层的具体的执行单元,比方 Flink 的 sub task。这样就实现了数据的并行读取,以及具体 split 的拆分和 reader 的映射关系。
4 状态复原
Reader 的状态复原其实和 Flink 和 Spark 的很多做法相似。
当过程宕掉或者呈现问题的时候,须要把 Reader 所有还没有读到的那些 split 以及正在读还没读完的 split,存储到对应的 state 外面,等状态复原后,从 state 状态里将其读出来,持续去生产、读取就能够了。
TDengine Connector 写入解析
1 数据提交写入流程
SeaTunnel 原生地反对两阶段提交的数据帮助保障,具体的实现逻辑是借助一个数据协调器叫 Sink coordinator,还有 Sink Writer,writer 运行在不同的 worker 下面,每一个 writer 独立实现事务的写入。
数据写入分成两步,第一步就是大家比拟常见的两阶段提交,先做预提交,之后把本人的 commit 信息反馈到协调器,等所有 worker 把提交信息的全副反馈完当前,由对立由 coordinator 协调器来实现最初的事务写入。
当然也有更简略的写法,间接由 worker 实现写入以及 commit 操作,不属于两阶段提交的领域。
2 元数据的辨认和注入
在 Sink 端,这是一条残缺的实在的 TDengine insert 语句,包含 subtable,通过从形象层的 SECAM rode 外面就能够间接提取到,因为 SeaTunnelRow 承载了一部分元数据的传输性能,所以从这里间接就能提取到。
第二局部就是 stable,须要在用户在配置文件中配置。然而 Supertable 上面的对应的 subtable 用户不须要配置和指定,导过去的字段中,tag 和 valve 混淆,在隐衷的语句里须要离开实现,所以在这里也是 connector 从 TDengine 的 元数据里读取信息,做自动识别,从 SeaTunnelRow 中辨认 tag 和 valve,并把它们安放在不同的地位上,实现一个具体的插入过程。
所以,只须要用户配置 stable 这一项。这里用到了一些元数据的注入工作,能够缩小大家的配置复杂度。
另外,对于时区的配置,因为 TDengine 是时序数据库,导入导出场景下对于时区配置有着特地要求,咱们针对这个场景做了一些时区参数配置,能够动静指定时区。
TDengine Connector 应用示例
上面展现一个 TDengine Connector 的应用示例,看看最终的成果。
我以在 TDengine 实例之间做数据传输为例。当然其余数据场景也是反对的,只须要换对应的 Source 插件和 Sink 插件即可。
能够看到,Source 其实除了 URL username、password 基本参数以外,只须要配置一个 stable,就是你的表,以及它的上工夫序列的上下界即可。
Reserve table name 是对应到如果有 transform 过程的话,须要用到配置,如果要是没有转换的过程,这一个参数配置也是不是必须的。Sink 端也是对应基本参数配置,只是多了一项 timezone,就是时区的配置。
上图为导入、导出之后的效果图,对应的数据指标和 tag 都能够比拟正当地安顿在不同的地位上做同步。
TDengine Connector 的下一步打算
● Source 端:
- 反对 streaming 数据集成(目前仅反对 batch 操作)
● Sink 端:
- 反对数据写入异样重试机制
- 反对数据批量写入(目前仅反对批量读取,单条写入)
如何参加奉献
最初跟大家简略分享一下,新同学怎么动手参加社区奉献。
● 寻找你感兴趣的 issue
- https://github.com/apache/incubator-seatunnel/issues/2828
- https://github.com/apache/incubator-seatunnel/issues/3018
- https://github.com/apache/incubator-seatunnel/issues?q=is:open+is:issue+label:”help+wanted”
● 参考奉献指南
* https://github.com/apache/incubator-seatunnel/issues/2828
* https://github.com/apache/incubator-seatunnel/pull/2995【奉献指南】* https://github.com/apache/incubator-seatunnel/blob/dev/docs/en/contribution/setup.md【编译指南】
● 老手教程
- 【SeaTunnel 连接器极简开发流程】
- 【新 API Connector 开发解析】
- 【Source 与 Sink API 设计解析】
● 参加探讨 & 寻求帮忙
- 在邮件列表、Slack 中探讨
- 通过微信群沟通(如果没有退出请关注 SeaTunnel 公众号入群)
-
参加 PR Review 发表你的见解
本文由 白鲸开源科技 提供公布反对!