赞
踩
摘要:本文整理自阿里巴巴开发工程师,Apache Flink Committer 任庆盛,在 9 月 24 日 Apache Flink Meetup 的分享。主要内容包括:
广义概念上,能够捕获数据变更的技术统称为 CDC(Change Data Capture)。通常我们说的 CDC 主要面向数据库的变更,是一种用于捕获数据库中数据变化的技术。
CDC 的主要应用有三个方面:
按照实现机制,CDC 可以分为两种类型:基于查询和基于日志的 CDC。基于查询的 CDC 通过定时调度离线任务的方式实现,一般为批处理模式,无法保证数据的实时性,数据一致性也会受到影响。基于日志的 CDC 通过实时消费数据库里的日志变化实现,如通过连接器直接读取 MySQL 的 binlog 捕获变更。这种流处理模式可以做到低延迟,因此更好地保障了数据的实时性和一致性。
在上图中,我们比较了几种常见的 CDC 方案。相比于其他方案,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 恢复读取。
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 发布公告: https://mp.weixin.qq.com/s/eowlSueG-MamwVQwUkSzSQ
上图展示了一个典型的数据同步场景,源数据库中的变更数据使用 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 实时数据集成的解决方案有如下几个优势:
数据库中有三张表,分别是产品、订单、运输表。通过 CDAS 整库同步能力,将数据一次性同步到 Kafka 中,下游有多条业务线来消费 Kafka 里数据。Flink 作业将前面三张表做 join,打成宽表。如果没有中间的 Kafka 或同步能力,则需要起多个 Flink 作业,消费源库中某两个或多个数据表的变更数据,比如 order 表,本身可能变化非常快,会对数据库产生非常大的压力。我们将通过 demo 来演示如何解决该问题。
本文为阿里云原创内容,未经允许不得转载。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。