1.Flink CDC:基于 Apache Flink 的源码流式数据集成框架
2.SeaTunnel连接器V1到V2的架构演进与探究
3.Flink 十大技术难点实战 之九 如何在 PyFlink 1.10 中自定义 Python UDF ?
4.盘点 35 个 Apache 顶级项目,我拜服了…
5.Apache Hudi X Apache Kyuubi,分析中国移动云湖仓一体的源码探索与实践
6.Flink系列十九Flink 作业Hadoop 依赖冲突解决NoSuchMethodError
Flink CDC:基于 Apache Flink 的流式数据集成框架
摘要:本文整理自阿里云 Flink SQL 团队研发工程师于喜千(yux)在 SECon 全球软件工程技术大会中数据集成专场沙龙的分享。内容主要为以下四部分: 1. Flink CDC 开源社区介绍; 2. Flink CDC 的分析演进历史; 3. Flink CDC 3.x 核心特性解读; 4. 基于Flink CDC 的实时数据集成实践。
1. **Flink CDC 开源社区介绍
**- **1.1 Flink CDC 的源码演进历史
**- Flink CDC 从 GitHub 开源社区开始,于 年 7 月在 Ververica 公司的分析物流转运软件源码 GitHub 仓库下以 Apache 2.0 协议开放源代码。初期主要支持从 MySQL 和 PG SQL 数据库捕获变化数据。源码2.0 版本增强了运行效率、分析稳定性和故障恢复机制,源码并扩展了源数据库支持范围至 Oracle、分析MongoDB 实时数据抽取。源码
- 年 月发布的分析 CDC 3.0 版本引入了 YAML pipeline 作业,使其成为独立的源码端到端数据集成框架,通过简化语法提供更便捷的分析数据集成作业描述。
- **1.2 Flink CDC 社区现状
**- CDC 作为 Flink 的源码一个子项目,于 年初正式加入 Apache 软件基金会,遵循 ASF 标准进行迭代开发。截至最新版本 3.1.1,累计超过 名贡献者提交了 余次代码提交,GitHub 收获超过 颗 star。
- 社区生态多元,GitHub Top 代码贡献者来自 家公司,600w源码覆盖 MongoDB、Oracle、Db2、OceanBase 等连接器及 Pipeline Transform 等核心功能。社区通过多种渠道保持与用户沟通,如钉钉群、邮件列表和 Slack 频道。
2. **Flink CDC 的演进历史
**- **2.1 CDC 技术简介
**- CDC 技术专注于实时监控数据变更,并将变化记录实时写入数据流,用于数据同步、分发和加载到数据仓库或数据湖。技术包括 Query-based CDC 和 Log-based CDC,后者通过监听数据库日志来实现低延迟变化捕获,减轻数据库压力,确保数据处理一致性。
- **2.2 早期 CDC 技术局限
**- 早期实现存在实用性问题,如依赖数据库查询、并发处理和状态管理的复杂性,以及对数据库性能的高要求。
- **2.3 Flink CDC 接入增量快照框架
**- Flink CDC 2.0 引入增量快照算法,支持任意多并发快照读取,蓝牙芯片源码无需数据库加锁,实现故障恢复。通过 Netflix DBlog 论文中的无锁快照算法,实现了高效并发处理。
- **2.4 Flink CDC 增强
**- 引入 SplitEnumerator 和 Reader 架构,实现数据源的逻辑划分和并发读取,增强了处理效率和吞吐量。支持 Schema Evolution,允许在不重启作业的情况下处理表结构变更,提高了作业的稳定性和维护性。
3. **Flink CDC 3.0 核心特性解读
**- **3.1 Flink CDC 2.x 版本回顾
**- CDC 2.x 版本提供 SQL 和 Java API,但缺乏直观的 YAML API 和高级进阶能力支持。
- **3.2 Flink CDC 3.0 设计目标
**- 3.0 版本引入 YAML API,提供端到端数据集成流程描述。支持 Schema Evolution、Transform 和路由功能,增强数据处理灵活性。
- **3.3 Flink CDC 3.0 核心架构
**- 采用无状态设计,简化部署和运维。分离连接层,保留对 Flink 生态系统的秒赞云源码兼容性,支持多样化的部署架构和集群环境。
- **3.4 Flink CDC 3.0 API 设计
**- YAML API 提供直观的数据集成任务配置,支持转换、过滤、路由等高级功能,简化了开发和配置流程。
- **3.5 Flink CDC 3.0 Schema Evolution 功能
**- 提供了在不重启作业的情况下处理表结构变更的机制,确保数据处理的一致性和稳定性。
4. **基于 Flink CDC 的实时数据集成实践
**- **4.1 实例:MySQL 到 Kafka 实时传输
**- Flink CDC 3.0 内建 Kafka 输出连接器,简化了 MySQL 数据至 Kafka 的实时传输过程,无需额外基础设施配置。
- **4.2 实时数据集成实践
**- Flink CDC 3.0 支持模式进化、列操作和丰富的内置函数,提供了高度可定制的预处理能力,提升数据处理的灵活性与效率。
总结:Flink CDC 是一个高效、易用的实时数据集成框架,通过不断演进优化,满足了数据同步、分发和加载到数据仓库或数据湖的需求。社区活跃,轻云应用源码支持多渠道沟通,鼓励代码贡献和用户参与,是实时数据处理领域的有力工具。
SeaTunnel连接器V1到V2的架构演进与探究
核心概念
SeaTunnel设计的核心是利用设计模式中的控制翻转或依赖注入,主要包括以下两点:
数据处理过程大致分为输入 -> 转换 -> 输出,更复杂的数据处理实质上也是这些行为的组合。
内核原理
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
在基础模块中,有以下代码:
为了更清晰地理解这些类之间的关系,笔者制作了一张简单的UML类图:
整个API的组成可以大体分为三部分:构建层接收命令参数构建执行器,执行器初始化上下文,上下文注册插件并启动插件,至此,整个作业开始运行。
seatunnel-api-spark
在Spark引擎API层有以下代码:
同样,笔者整理了一张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的详细信息,读者可以参考:mon加载了TraceUtils,但实际加载的是2.7.x版本的TraceUtils。因此,问题出在版本兼容性上。有以下两种解决方案:
第一类解决方案是手动从jar包中排除冲突依赖。这需要识别冲突的库,并在Flink构建过程中排除它们,确保加载的库版本与期望一致。
第二类解决方案是通过打包工具精确排除字节码。这可以更细致地控制类加载过程,避免不兼容版本的类被加载。
深入理解这一问题,有助于我们意识到在使用Flink与外部系统集成时,版本兼容性是一个不容忽视的挑战。为避免此类问题,需要仔细管理依赖库的版本,确保它们之间无冲突。
解决此类问题的最新方法(适用于所有Flink版本)在上一篇文章中已有详细描述,参见Flink系列十八HDFS_DELEGATION_TOKEN过期的问题解决汇总。