1.如何评价datax的码解应用?
2.SeaTunnel连接器V1到V2的架构演进与探究
3.工具Datax的基本概念(初识ETL工具)
4.大数据技术之Datax
5.DataX任务容器
6.如何更改 datax 以支持hive 的 DECIMAL 数据类型?
如何评价datax的应用?
为了改进datax任务进度信息展示方式,我们计划对源码进行改造,码解将实时任务进度信息结构化存储在redis服务器中,码解让前端通过轮询实时从redis中获取进度信息,码解从而提供给用户更友好的码解体验。
在分析datax任务进度信息的码解制作APP的源码打印逻辑时,我们发现这些信息首先被task group汇总收集,码解然后由job进一步汇总收集。码解因此,码解job能够收集并汇总所有任务的码解进度信息。
进一步探究,码解我们了解到JobContainer依赖的码解Scheduler会周期性打印job收集汇总的进度信息。具体实现可见于源码中的码解com.alibaba.datax.core.job.scheduler.AbstractScheduler#schedule函数,以及com.alibaba.datax.core.statistics.container.communicator.job.StandAloneJobContainerCommunicator#report函数。码解
了解了datax的码解无界源码hook机制后,我们能够设计实现从datax实时获取并持久化进度信息至redis的功能。关键在于,我们可以在打印进度信息的时机触发invokeHook方法,通过配置信息和进度信息作为参数,调用自定义实现的Hook类的invoke方法。具体地,我们设计了一个名为RedisReportHook的自定义Hook类,用于将进度信息持久化至redis。
SeaTunnel连接器V1到V2的架构演进与探究
核心概念
SeaTunnel设计的核心是利用设计模式中的控制翻转或依赖注入,主要包括以下两点:
数据处理过程大致分为输入 -> 转换 -> 输出,更复杂的数据处理实质上也是这些行为的组合。
内核原理
SeaTunnel将数据处理的各种行为抽象成Plugin,并使用SPI技术进行动态注册,设计思路保证了框架的emojimix 源码灵活扩展。在以上理论基础上,数据的转换与处理还需要做统一的抽象,如著名的异构数据源同步工具DataX,也对数据单条记录做了统一抽象。
SeaTunnel V1架构体系中,由于背靠Spark和Flink两大分布式计算框架,框架已经为我们做好了数据源抽象的工作,Flink的DataStream、Spark的DataFrame已经是对接入数据源的高度抽象。在此基础上,我们只需要在插件中处理这些数据抽象即可。同时,借助Flink和Spark提供的SQL接口,还可以将每次处理完的timesyncd 源码数据注册成表,方便用SQL进行处理,减少代码的开发量。
实际上,SeaTunnel的最终目的是自动生成一个Spark或Flink作业,并提交到集群中运行。
SeaTunnel连接器V1 API解析架构概览
目前在项目dev分支下,SeaTunnel连接器V1 API所在的模块如图所示:
seatunnel-api-base
在基础模块中,有以下代码:
为了更清晰地理解这些类之间的关系,笔者制作了一张简单的UML类图:
整个API的组成可以大体分为三部分:构建层接收命令参数构建执行器,执行器初始化上下文,上下文注册插件并启动插件,至此,整个作业开始运行。
seatunnel-api-spark
在Spark引擎API层有以下代码:
同样,eui源码笔者整理了一张UML类图来表示它们之间的关系:
整个流程与Base模块一致,在此不再赘述,有兴趣的读者可以自行查看源码。
seatunnel-api-flink
在Flink引擎API层有以下代码:
同样,笔者整理了一张UML类图来表示它们之间的关系:
整个流程与Base模块一致,在此不再赘述,有兴趣的读者可以自行查看源码。
SeaTunnel连接器V1运行原理启动器模块概览
整个项目的最外层启动类都放在以下模块中:
与连接器V1有关的模块如下:
执行流程
为了更好地理解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。读者如果想直接深入了解作业启动核心流程的话,推荐阅读这两个类的源码。
执行原理SparkFlinkSeaTunnel连接器V2 API解析架构概览
目前在项目dev分支下,SeaTunnel连接器V2 API所在的模块如图所示:
数据抽象
SeaTunnel连接器V2 API在数据层面做了抽象,定义了自己的数据类型,这是与连接器V1最大的不同点。连接器V1使用的是引擎数据抽象的能力,但连接器V2自己提供了这个异构数据源统一的能力。
在所有的Source连接器和Sink连接器中,处理的都是SeaTunnelRow类型数据,同时SeaTunnel也对内设置了数据类型规范。所有通过Source接入进来的数据会被对应的连接器转化为SeaTunnelRow送到下游。
API Common
在API common包下有以下接口的定义:
在这里,由于篇幅关系,只介绍比较核心的几个接口:
具体接口中有哪些方法,读者可以自行阅读对应类的源码,在此不再赘述。
API Source
在API source包下有以下接口的定义:
在这里,由于篇幅关系,只介绍比较核心的几个接口:
API Sink
在API sink包下有以下接口的定义:
在这里,由于篇幅关系,只介绍比较核心的几个接口:
小结
连接器V2在架构分层上与计算引擎进行解耦,定义了自己的元数据定义以及数据类型定义,在API层和计算引擎层增加了翻译层,将SeaTunnel自定义的数据源通过翻译层接入到引擎中,从而真正实现接口和引擎分离的目的。
SeaTunnel连接器V2运行原理启动器模块概览
整个项目的最外层启动类都放在以下模块中:
与连接器V2有关的模块如下:
执行流程
为了更好地理解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的详细信息,读者可以参考:/session/apache-spark-data-source-v2。由于这篇文章的主题并不是介绍Spark的特性,所以在此不再赘述。
SeaTunnel V2 on Flink
SeaTunnel Source连接器V2将异构数据源接入,生成以SeaTunnelRow为基本单位的数据源,同时在翻译层实现了Flink source function和Flink sink function。翻译层使得Flink可以接入以SeaTunnelRow为基本单位的数据源,从而实现无缝接入Flink的目的。
关于Flink source Function和Flink sink function的详细信息,读者可以参考:.alibaba.datax.common.element.DoubleColumn#asBigDecimal,基于DoubleColumn底层rawData存储的原始数据内容,将字段值转换为合适的外部数据类型。这一过程不会损失数据精度。
综上所述,通过修改datax的HDFS Reader和Writer插件,实现对Hive DECIMAL数据类型的读取和写入支持,确保数据迁移过程的准确性和完整性,从而满足复杂数据迁移场景的需求。