乐趣区

关于数据同步:SeaTunnel连接器V1到V2的架构演进与探究

外围概念

整个 SeaTunnel 设计的外围是利用设计模式中的 管制翻转 或者叫 依赖注入,次要概括为以下两点:

  1. 下层不依赖底层,两者都依赖形象
  2. 流程代码与业务逻辑应该拆散

对于整个数据处理过程,大抵能够分为以下几个流程:输出 -> 转换 -> 输入,对于更简单的数据处理,本质上也是这几种行为的组合:

内核原理

SeaTunnel 将数据处理的各种行为形象成 Plugin,并应用SPI 技术进行动静注册,设计思路保障了框架的灵便扩大,在以上实践根底上,数据的转换与解决还须要做对立的形象,譬如比拟有名异构数据源同步工具DataX,也同样对数据单条记录做了对立形象。

在 SeaTunnel V1 架构体系中,因为背靠 Spark 和 Flink 两大分布式计算框架,框架曾经为咱们做好了数据源形象的工作,Flink 的 DataStream、Spark 的DataFrame 曾经是对接入数据源的高度形象,在此基础上咱们只须要在插件中解决这些数据抽象即可,同时借助于 Flink 和 Spark 提供的 SQL 接口,还能够将每一次解决完的数据注册成表,不便用 SQL 进行解决,缩小代码的开发量。

实际上 SeaTunnel 最初的目标是主动生成一个 Spark 或者一个 Flink 作业,并提交到集群中运行。

SeaTunnel 连接器 V1 API 解析

架构概览

目前在我的项目 dev 分支下,SeaTunnel 连接器 V1 API 所在的模块如图所示:

  • seatunnel-api-base:根底 API 层形象
  • seatunnel-api-flink:Flink 引擎 API 层形象
  • seatunnel-api-spark:Spark 引擎 API 层形象

seatunnel-api-base

在根底模块中,有以下代码:

为了更清晰的了解这些类之间的关系,笔者这里制作了一张简略的 UML 类图:

整个 API 的组成能够大体分为三局部:

  1. 插件层:提供 Source、Transform、Sink 插件定义
  2. 执行层:提供执行器和运行上下文定义
  3. 构建层:提供命令行接口定义

构建层接管命令参数构建执行器,执行器初始化上下文,上下文注册插件并启动插件,至此,整个作业开始运行。

seatunnel-api-spark

在 Spark 引擎 API 层有以下代码:

同样,笔者也整顿了一张 UML 类图来示意它们之间的关系:

整个流程与 Base 模块统一,在这里笔者不过多赘述,有趣味的读者能够自行观看源码。

seatunnel-api-flink

在 Flink 引擎 API 层有以下代码:

同样,笔者也整顿了一张 UML 类图来示意它们之间的关系:

整个流程与 Base 模块统一,在这里笔者不过多赘述,有趣味的读者能够自行观看源码。

SeaTunnel 连接器 V1 运行原理

启动器模块概览

整个我的项目的最外层的启动类都放在以下模块中:

跟连接器 V1 无关的模块如下:

  • seatunnel-core-base:V1 根底启动模块
  • seatunnel-core-flink:V1flink 引擎启动模块
  • seatunnel-core-flink-sql:V1flink-sql 引擎启动模块
  • seatunnel-core-spark:V1spark 引擎启动模块

执行流程

为了更好的了解 SeaTunnel V1 的启动流程,笔者在这里制作了一张简略的时序图:

程序最外层的启动由 start-seatunnel-${engine}.sh 开始,用户依据将配置文件从脚本传入,脚本调用 org.apache.seatunnel.core.spark.SparkStarter 或者 org.apache.seatunnel.core.flink.FlinkStarter,实际上这个类只做一个工作:将所有参数拼接成spark-submit 或者 flink 命令,而后脚本接管到 spark-submit 或者 flink 命令并提交到集群中;提交到集群中真正执行 job 的类实际上是 org.apache.seatunnel.spark.SeatunnelSpark 或是org.apache.seatunnel.flink.SeatunnelFlink,读者如果想间接深刻理解作业启动外围流程的话举荐浏览这两个类的源码。

执行原理

Spark

  1. SparkSource 插件将异构数据源接入为 DataFrame
  2. SparkTransform 插件将 SparkSource 接入的 DataFrame 进行转换解决
  3. SparkSink 插件将 SparkTransform 解决好的 DataFrame 写入到指标数据源

Flink

  1. FlinkSource 插件将异构数据源接入为 DataStream
  2. FlinkTransform 插件将 FlinkSource 接入的 DataStream 进行转换解决
  3. SparkSink 插件将 FlinkTransform 解决好的 DataStream 写入指标数据源

SeaTunnel 连接器 V2 API 解析

架构概览

目前在我的项目 dev 分支下,SeaTunnel 连接器 V2 API 所在的模块如图所示:

  • seatunnel-api:连接器 V2 所有的 API 定义

数据抽象

SeaTunnel 连接器 V2 API 在数据层面做了形象,定义了本人的数据类型,这是与连接器 V1 最大的不同点,连接器 V1 应用的是引擎数据抽象的能力,然而连接器 V2 本人提供的这个异构数据源对立的能力:

在所有的 Source 连接器和 Sink 连接器中,解决的都是 SeaTunnelRow 类型数据,同时 SeaTunnel 也对内设置了数据类型标准,所有通过 Source 接入进来的数据会被对应的连接器转化为 SeaTunnelRow 送到上游。

API Common

在 API common 包下有以下接口的定义:

在这里因为篇幅关系只介绍比拟外围的几个接口:

  • PluginIdentifierInterface:插件惟一标识
  • SeaTunnelContext:SeaTunnel 利用上下文,每个 SeaTunnel Job 蕴含的上下文对象,保留了以后源表的元数据
  • SeaTunnelPluginLifeCycle:插件申明周期

具体接口中有哪些办法读者能够自行浏览对应类的源码,在这里笔者将不过多赘述。

API Source

在 API source 包下有以下接口的定义:

在这里因为篇幅关系只介绍比拟外围的几个接口:

  • Boundedness:标识数据有界无界,连接器 V2 设计理念基于批流一体,此接口用于区分流式作业还是批式作业
  • Collector:数据收集器,用于收集 Source 连接器产生的数据并推往上游
  • SeaTunnelSource:Source 插件基类,所有的 Source 连接器主类均继承于这个接口
  • SourceReader:Source 插件真正解决数据接入的接口
  • SourceSplit:数据分片接口,连接器 V2 反对数据并行读入,晋升数据接入效率
  • SourceSplitEnumerator:数据分片器,此接口用于散发数据分片至对应的 SourceReader 中

API Sink

在 API sink 包下有以下接口的定义:

在这里因为篇幅关系只介绍比拟外围的几个接口:

  • SeaTunnelSink:Sink 插件基类,所有的 Sink 连接器均继承于这个接口
  • SinkWriter:Sink 插件真正实现数据输入的接口
  • SinkCommitter:用于解决 SinkWriter#prepareCommit 返回的数据信息,蕴含须要提交的事务信息,连接器 V2 在 Sink 设计上提供二阶段提交的接口,从而使连接器有了实现 Exactly-Once 的可能性
  • SinkAggregatedCommitter:用于解决 SinkWriter#prepareCommit 返回的数据信息,蕴含须要提交的事务信息等,用于在单节点多任务一起提交事务信息,这样能够防止提交阶段二局部失败导致状态不统一的问题(注:在实现连接器时优先实现这个接口,这样会兼容性更强)

小结

连接器 V2 在架构分层上与计算引擎进行解耦,定义了本人的元数据定义以及数据类型定义,在 API 层和计算引擎层减少了翻译层,将 SeaTunnel 自定义的数据源通过翻译层接入到引擎中,从而真正实现接口和引擎拆散的目标。

SeaTunnel 连接器 V2 运行原理

启动器模块概览

整个我的项目的最外层的启动类都放在以下模块中:

跟连接器 V2 无关的模块如下:

  • seatunnel-core-starter:V2 根底启动模块
  • seatunnel-flink-starter:V2flink 引擎启动模块
  • seatunnel-spark-starter:V2spark 引擎启动模块

执行流程

为了更好的了解 SeaTunnel V2 的启动流程,笔者在这里制作了一张简略的时序图:

程序最外层的启动由 start-seatunnel-${engine}-new-connector.sh 开始,用户依据将配置文件从脚本传入,脚本调用 org.apache.seatunnel.core.spark.SparkStarter 或者 org.apache.seatunnel.core.flink.FlinkStarter,实际上这个类只做一个工作:将所有参数拼接成spark-submit 或者 flink 命令,而后脚本接管到 spark-submit 或者 flink 命令并提交到集群中;提交到集群中真正执行 job 的类实际上是 org.apache.seatunnel.spark.SeatunnelSpark 或是org.apache.seatunnel.flink.SeatunnelFlink,读者如果想间接深刻理解作业启动外围流程的话举荐浏览这两个类的源码,连接器 V2 和连接器 V1 的启动流程基本一致。

SeaTunnel V2 on Spark

SeaTunnel Source 连接器 V2 将异构数据源接入,生成以 SeaTunnelRow 为根本单位的数据源,在翻译层实现了 Spark DataSource API V2,翻译层使得 Spark 能够接入以SeaTunnelRow 为根本单位的数据源,从而实现无缝接入 Spark 的目标。

对于 Spark DataSource API V2 的详细信息,读者能够参考:https://www.databricks.com/se…,因为这篇文章的主题并不是介绍 Spark 的个性,所以笔者在这里不过多赘述。

SeaTunnel V2 on Flink

SeaTunnel Source 连接器 V2 将异构数据源接入,生成以 SeaTunnelRow 为根本单位的数据源,同时在翻译层实现了 Flink source functionFlink sink function,翻译层使得 Flink 能够接入以 SeaTunnelRow 为根本单位的数据源,从而实现无缝接入 Flink 的目标。

对于 Flink source FunctionFlink sink function的详细信息,读者能够参考:https://nightlies.apache.org/…,因为这篇文章的主题并不是介绍 Flink 的个性,所以笔者在这里不过多赘述。

执行原理

Source 连接器接入数据源为 SeaTunnelRow,Translation 层转换 SeaTunnelRow 数据源为各种计算引擎外部的数据源,Sink 连接器接管计算引擎外部转换好的 SeaTunnelRow 数据源并写入到指标数据源中。

V1 API vs V2 API

特色 连接器 V1 连接器 V2
引擎依赖 强依赖 Spark、Flink 无依赖
连接器实现 针对不同引擎要实现屡次 只实现一遍
引擎版本升级难易水平 较难,连接器与引擎高度耦合 较易,针对不同版本开发不同翻译层即可
连接器参数是否对立 针对不同引擎可能会有不同参数 参数对立
自定义分片逻辑 依赖 Spark、Flink 曾经实现好的数据 Connector,分片逻辑不可控 分片逻辑可自定义

将来瞻望

目前社区正在做的事件:

  1. 连接器接入,社区打算在年底接入 80+ 种数据源
  2. Web 服务化,社区目前在做 Web 服务化相干工作,用户可依据 Web 界面进行作业的治理、日志查看、高低线操作
  3. 计算引擎开发,社区目前在开发本人的计算引擎,更专一于数据同步,晋升性能

将来指标:

  1. 性能优化,多维度指标监控,准确流速管制,可视化大屏监控
  2. 可视化利落拽疾速生成数据集成工作
  3. 更多调度平台无缝接入

最终目标:胜利从 Apache 孵化器毕业,成为世界一流的诞生于中国的数据集成平台工具

贡献者招募

目前社区正在蓬勃向前倒退,大量 feature 须要去开发实现,毕业之路道阻且艰,期待更多的有志之士参加到社区共建,欢送酷爱开源的小伙伴退出 SeaTunnel 社区,有意者可发邮件至 [email protected] 或微信 tyrantlucifer 分割我征询相干事宜,让咱们一起用开源点燃璀璨的程序人生。

退出移动版