Graphical DataX core design principles

Click "Middleware Interest Circle" above and select "Set as Star"

Be a positive person, the harder you work, the luckier you get!

DataX is a heterogeneous data source offline synchronization tool open sourced by Alibaba. It is committed to realizing stable and efficient synchronization between various heterogeneous data sources including relational databases (MySQL, Oracle, etc.), HDFS, Hive, ODPS, HBase, FTP, etc. Data synchronization function.

Some time ago, I mentioned the data synchronization project in K8s related articles. This project is built based on the DataX kernel. Due to the company's data synchronization requirements, it is necessary to support the incremental synchronization function on the basis of the original DataX, while supporting Distributed scheduling, the implementation of which has been described in detail in the article " Job Scheduling Practice Sharing Using K8s ".

Based on my practice of DataX in the project, I will share with you the core design principles of DataX that I understand.

design concept

Offline synchronization of heterogeneous data sources is to synchronize the source data to the destination, but there are many types of end-to-end data sources. Before DataX, the end-to-end links will form a complex mesh structure, which is very scattered and cannot be synchronized. The core logic is abstracted, and the concept of DataX is to connect various data sources as a synchronization core carrier. When we need data synchronization, we only need to connect to DataX in the form of plug-ins, which can transform the complex network structure link into a data source. It becomes a star structure, as shown in the following figure:

Architecture design

Anyone who has used IDEA knows that IDEA has many great plug-ins. Users can download relevant plug-ins according to their own programming needs. DataX also uses this pluggable design and adopts the framework design of Framework + Plugin, as shown below. shown:

With plug-ins, DataX can support any data source to data source. As long as the Reader/Writer Plugin is implemented, the official has implemented mainstream data source plug-ins, such as MySQL, Oracle, SQLServer, etc. Of course, we can also develop a DataX plug-in.

Core idea

DataX 核心主要由 Job、Task Group、Task、Channel 等概念组成:

1、Job

在 DataX 中用来描述一个源端到一个目的端的同步作业,是 DataX 数据同步面向用户的最小业务单元。一个Job 对应 一个 JobContainer, JobContainer 负责 Job 的全局切分、调度、前置语句和后置语句等工作。

2、Task Group

一组 Task 的集合,根据 DataX 的公平分配策略,公平地分配 Task 到对应的 TaskGroup 中。一个 TaskGroup 对应一个 TaskGroupContainer,负责执行一组 Task。

3、Task

Job 的最小执行单元,一个 Job 可根据 Reader 端切分策略,且分成若干个 Task,以便于并发执行。

Job、Task Group、Task 三者之间的关系可以用如下图表示:

根据切分策略将一个 Job 切分成多个 Task,根据分配策略将多个 Task 组成一个 TaskGroup。

4、Channel

DataX 会单独启动一条线程运行运行一个 Task,而 Task 会持有一个 Channel,用作 Reader 与 Writer 的数据传输媒介,DataX 的数据流向都是按照 Reader—>Channel—>Writer 的方向流转,用如下图表示:

Channel 作为传输通道,即能充当缓冲层,同时还能对数据传输进行限流操作。

5、Transformer

DataX 的 transformer 模式同时还提供了强大的数据转换功能,DataX 默认提供了丰富的数据转换实现类,用户还可以根据项目自身需求,扩展数据转换。

调度流程

DataX 将用户的 job.json 同步作业配置解析成一个 Job,DataX 通过 JobContainer 完成全局切分、调度、前置语句和后置语句等工作,整体调度流程用如下图表示:

1、切分策略

1)计算并发量(即 needChannelNumber 大小)

DataX有流控模式,其中,可以设置 bps 限速,tps 限速:

  • bps 限速:needChannelNumber = 总 byteLimit / 单个 Channel byteLimit

  • tps 限速:needChannelNumber = 总 recordLimit / 单个 Channel recordLimit

如果以上都没有设置,则会根据用户在 job.setting.speed.channel 配置的并发数量设置 needChannelNumber。

2)根据 needChannelNumber 将 Job 切分成多个 Task

这个步骤的具体切分逻辑交由相关插件去完成,例如 Rdb 对数据的拆分主要分成两类:

  • 如果用户配置了具体的 Table 数量,那么就按照 Table 为最小单元进行拆分(即一个 Table 对应一个 Task),并生成对应的 querySql;
  • 如果用户还配置了 splitPk,则会根据 splitPk 进行切分,具体逻辑是根据 splitPk 区间对 Table 进行拆分,并生成对应的 querySql。

2、公平分配策略

DataX 在执行调度之前,会调用 JobAssignUtil#assignFairly方法对切分好的 Task 公平分配给每个 TaskGroup。

在分配之前,会计算 TaskGroup 的数量,具体公式:

int taskGroupNumber = (int) Math.ceil(1.0 * channelNumber / channelsPerTaskGroup);

channelNumber 即为在切分策略中根据用户配置计算得到的 needChannelNumber 并发数量大小,channelsPerTaskGroup 为每个 TaskGroup 需要的并发数量,默认为 5。

求出 TaskGroup 的数量之后,就会执行公平分配策略,将 Task 平均分配个每个 TaskGroup,最后执行调度,完成整个同步作业。举个公平分配策略的例子:

假设 A 库有表 0、1、2,B 库上有表 3、4,C 库上有表 5、6、7,如果此时有 4 个 TaskGroup,则 assign 后的结果为:

taskGroup-0: 0,  4,
taskGroup-1: 3,  6,
taskGroup-2: 5,  2,
taskGroup-3: 1,  7

举个例子来描述 Job、Task、Task Group 之间的关系:

用户构建了一个数据同步作业,该作业的目的是将 MySql 的 100 张表同步到 Oracle 库中,假设此时用户设置了 20 个并发(即 channelNumber=20):

  1. DataX 根据表的数量切分成 100 个 Task;
  2. DataX 默认给每个 TaskGroup 分配 5 个 Channel,因此 taskGroupNumber = channelNumber / channelsPerTaskGroup = 20 / 5 = 4;
  3. 根据 DataX 的公平分配策略,会将 100 个 Task 平均分配给每个 TaskGroup,因此每个 TaskGroup 处理 taskNumber / taskGroupNumber = 100 / 4 = 25 个 Task。

以上的例子用如下图表示:

由于一个 Channel 对应一个线程执行,因此 DataX 的线程模型可以用如下图表示:

作者介绍:作者张乘辉,擅长消息中间件技能,负责公司百万 TPS 级别 Kafka 集群的维护,公号不定期分享 Kafka、RocketMQ 系列不讲概念直接真刀真枪的实战总结以及细节上的源码分析;同时作者也是阿里开源分布式事务框架 Seata Contributor,因此也会不定期分享关于 Seata 的相关知识;当然公号也会不定期发表 WEB 相关知识比如 Spring 全家桶等。不一定面面俱到,但一定让你感受到作者对于技术的追求是认真的!

本文分享自微信公众号 - 中间件兴趣圈(dingwpmz_zjj)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324029998&siteId=291194637