摘要:本文整理自阿里巴巴开发工程师、Apache Flink Committer 任庆盛,在 9 月 24 日 Apache Flink Meetup 的分享。主要内容包括:
Flink CDC 技术对比与分析
Flink + Kafka 实时数据集成方案
Demo:Flink+Kafka 实现 CDC 数据的实时集成和实时分析
Tips:点击「阅读原文」查看原文视频&演讲 ppt
1.1 变更数据捕获(CDC)技术
广义概念上,能够捕获数据变更的技术统称为 CDC(Change Data Capture)。通常我们说的 CDC 主要面向数据库的变更,是一种用于捕获数据库中数据变化的技术。- 数据同步,通过 CDC 将数据同步到其他存储位置来进行异地灾备或备份。
- 数据分发,通过 CDC 将数据从一个数据源抽取出来后分发给下游各个业务方做数据处理和变换。
- 据采集,使用 CDC 将源端数据库中的数据读取出来后,经过 ETL 写入数据仓库或数据湖。
按照实现机制,CDC 可以分为两种类型:基于查询和基于日志的 CDC。基于查询的 CDC 通过定时调度离线任务的方式实现,一般为批处理模式,无法保证数据的实时性,数据一致性也会受到影响。基于日志的 CDC 通过实时消费数据库里的日志变化实现,如通过连接器直接读取 MySQL 的 binlog 捕获变更。这种流处理模式可以做到低延迟,因此更好地保障了数据的实时性和一致性。
1.2 Flink CDC 的技术优势
在上图中,我们比较了几种常见的 CDC 方案。相比于其他方案,Flink CDC 在功能上集成了许多优势:- 在实现机制方面,Flink CDC 通过直接读取数据库日志捕获数据变更,保障了数据实时性和一致性。
- 在同步能力方面,Flink CDC 支持全量和增量两种读取模式,并且可以做到无缝切换。
- 在数据连续性方面,Flink CDC 充分利用了 Apache Flink 的 checkpoint 机制,提供了断点续传功能,当作业出现故障重启后可以从中断的位置直接启动恢复。
- 在架构方面,Flink CDC 的分布式设计使得用户可以启动多个并发来消费源库中的数据。
- 在数据变换方面,Flink CDC 将从数据库中读取出来后,可以通过 DataStream、SQL 等进行各种复杂计算和数据处理。
- 在生态方面,Flink CDC 依托于强大的 Flink 生态和众多的 connector 种类,可以将实时数据对接至多种外部系统。
1.3 Flink CDC 全增量一体化框架
自 2.0 版本起,Flink CDC 引入了增量快照框架,实现了数据库全量和增量数据的一体化读取,并可以在全量和增量读取之间进行无缝切换。在读取全量数据时,Flink CDC source 会首先将数据表中的已有数据根据主键分布切分成多个 chunk(如上图中的绿色方块所示),并将 chunk 分发给多个 reader 进行并发读取。
对于数据变化频繁、已有数据较多的数据库,在全量同步过程中已同步的数据可能会发生变化。一些数据集成工具的解决方案是在读取前获取表锁阻止数据变更,再进行全量数据读取,然而这种方案会对在线业务造成较大影响。为解决该问题,Flink CDC 的增量快照框架引入了水位线(watermark)的概念:在启动全量同步前,首先获取数据库当前最新的 binlog 位点,记为低水位线(low watermark),如上图中的蓝色方块所示,随后启动全量读取。
在所有全量数据读取完成后,CDC source 会再次获取最新的 binlog 位点,并记为高水位线(high watermark),如上图中第二个蓝色方块所示。位于高低水位线之间、与被捕获表相关的 binlog 事件(上图中的黄色方块)即为全量数据在读取阶段发生的数据变化,CDC source 会将这部分增量数据合并至现有快照,合并完成后即可获得与源数据库完全一致的实时快照,并且在此过程中无需对数据库进行加锁,不会影响线上业务的正常运行。
业界常用的另一个 CDC 工具是 Debezium。与 Flink CDC 相比,Debezium 方案需要在全量读取前为数据库加锁,且只能使用单并发读取。如果在同步过程中任务发生失败,需要从全量数据重新读取才能够保证一致性。Flink CDC 的增量快照框架方案在全量读取前无需加锁,并且可以使用多并发读取。依托于 Flink checkpoint 机制,如果在同步过程中作业发生异常,可快速从最近一次成功的 checkpoint 恢复读取。1.4. Flink CDC 社区发展
Flink CDC 社区从 2020 年 7 月份创立至今受到了各位开发者的广泛关注,整个社区蓬勃发展。截至 2023 年 1 月,项目 star 数量超过 3000 个,超过 70 位贡献者提交了超过 500 个 commit,项目 fork 数量超过 1200 次。在此也特别感谢每一位参与 Flink CDC 的开发者为社区蓬勃发展做出的卓越贡献!2022 年 11 月,Flink CDC 社区发布了最新的 2.3 版本,对 MySQL CDC 进行了诸多稳定性和稳定性改进,新增了 Db2 CDC 连接器,MongoDB CDC 连接器接入了增量快照框架。详情可阅读 Flink CDC 2.3 发布公告。
上图展示了一个典型的数据同步场景,源数据库中的变更数据使用 Flink CDC 同步到下游。如果下游业务方较多、需要同步的数据库表较多或数据处理逻辑较复杂,由于每张数据表都需要启动一个 Flink 作业进行同步,这样会对源数据库造成极大压力。此外,某些热点表或数据库会被多个 Flink CDC 同步任务频繁访问,同样会加剧数据库的访问压力。为了解决以上业务痛点,一种可行的设计是在数据流水线中引入消息队列中间件的分布式能力,缓解数据库压力。比如先将源库中的变更数据同步到 Kafka 中,再由各个业务方消费。但引入消息队列后依然存在许多需要人工介入的问题,比如配置 CDC source、配置 Kafka sink、手动创建 Kafka topic 和 partition 等。另外,基于目前 Flink CDC 的设计,每一张表都需要启动一个同步作业,如果数据库里的表非常多,也会为源库带来很大的压力。
针对以上问题,阿里云实时计算平台推出了 Flink + Kafka 实时数据集成解决方案,用户使用一句 SQL 即可将数据库快速同步到 Kafka。解决方案使用了 CREATE TABLE AS(CTAS)语法和 CREATE DATABASE AS(CDAS)语法,指定源表名或源数据库名,以及目标表名或目标数据库名,即可快速将源库中的数据同步到目标 Kafka 中,无需手动配置配置任务和创建 Kafka topic / partition。
此外,解决方案还支持对源表的结构变更进行自动同步。如果源表中新加入可空列、删除可空列或重命名列,Kafka sink 会动态调整写入时使用的 JSON format,按照变更后的表结构将数据写入 Kafka 消息中。
按照 Flink CDC 当前的设计,在进行整库同步时,对数据库中的每张数据表都需要启动一个 Flink 作业进行消费,如果表数量非常多,Flink 作业数及其消耗的资源也会非常多。整库同步解决方案针对该问题进行了优化,在 Flink 作业中对同一个数据库复用一个 CDC source 实例,连接多个 sink 将不同表中的数据分发至不同的 Kafka topic,因此只需启动一个 Flink 作业即可同步数据库中的所有表。如果数据量非常大,也只需调节同步作业的并发,无需启动多个作业来对同一个数据库进行消费,大大降低 Flink 对于数据库连接数的压力。
Flink + Kafka 实时数据集成的解决方案有如下几个优势:- 只需要一条 SQL(CTAS、CDAS)即可完成单表或整库同步,无需反复配置作业参数来启动多个作业。
- 自动创建目标端 Kafka topic 和 partition,用户无需在 Kafka 集群中进行手动配置。
- 原生支持了添加可空列、删除可空列以及重命名列等表结构变更同步的策略,能够支持更多数据同步的场景。
03
Demo:Flink+Kafka 实现 CDC 数据的
实时集成和实时分析
数据库中有三张表,分别是产品、订单、运输表。通过 CDAS 整库同步能力,将数据一次性同步到 Kafka 中,下游有多条业务线来消费 Kafka 里数据。Flink 作业将前面三张表做 join,打成宽表。如果没有中间的 Kafka 或同步能力,则需要起多个 Flink 作业,消费源库中某两个或多个数据表的变更数据,比如 order 表,本身可能变化非常快,会对数据库产生非常大的压力。我们将通过 demo 来演示如何解决该问题。demo 演示可以点击「阅读原文」查看演讲视频 23:00-36:00 时间段。▼ 关注「Apache Flink」,获取更多技术干货 ▼