第 1 章 CDC 简介
1.1 什么是 CDC
CDC 是 Change Data Capture(变更数据获取)的简称。在广义的概念上,只要是能捕获数据变更的技术,我们都可以称之为 CDC 。核心思想是,监测并捕获数据库的变动(包括数据或数据表的插入、更新以及删除等),将这些变更按发生的顺序完整记录下来,写入到消息中间件中以供其他服务进行订阅及消费。
目前通常描述的 CDC 技术主要面向数据库的变更,是一种用于捕获数据库中数据变更的技术。CDC 技术的应用场景非常广泛:
- 数据同步:用于备份,容灾;
- 数据分发:一个数据源分发给多个下游系统;
- 数据采集:面向数据仓库 / 数据湖的 ETL 数据集成,是非常重要的数据源。
1.2 CDC 的种类
CDC 的技术方案非常多,目前业界主流的实现机制可以分为两种:
基于查询的 CDC:
离线调度查询作业,批处理。把一张表同步到其他系统,每次通过查询去获取表中最新的数据;
无法保障数据一致性,查的过程中有可能数据已经发生了多次变更;
不保障实时性,基于离线调度存在天然的延迟。
基于日志的 CDC:
实时消费日志,流处理,例如 MySQL 的 binlog 日志完整记录了数据库中的变更,可以把 binlog 文件当作流的数据源;
保障数据一致性,因为 binlog 文件包含了所有历史变更明细;
保障实时性,因为类似 binlog 的日志文件是可以流式消费的,提供的是实时数据。
对比增量同步能力,
基于日志的方式,可以很好的做到增量同步;
而基于查询的方式是很难做到增量同步的。
对比全量同步能力,基于查询或者日志的 CDC 方案基本都支持,除了 Canal。
而对比全量 + 增量同步的能力,只有 Flink CDC、Debezium、Oracle Goldengate 支持较好。
从架构角度去看,该表将架构分为单机和分布式,这里的分布式架构不单纯体现在数据读取能力的水平扩展上,更重要的是在大数据场景下分布式系统接入能力。例如 Flink CDC 的数据入湖或者入仓的时候,下游通常是分布式的系统,如 Hive、HDFS、Iceberg、Hudi 等,那么从对接入分布式系统能力上看,Flink CDC 的架构能够很好地接入此类系统。
在数据转换 / 数据清洗能力上,当数据进入到 CDC 工具的时候是否能较方便的对数据做一些过滤或者清洗,甚至聚合?
在 Flink CDC 上操作相当简单,可以通过 Flink SQL 去操作这些数据;
但是像 DataX、Debezium 等则需要通过脚本或者模板去做,所以用户的使用门槛会比较高。
另外,在生态方面,这里指的是下游的一些数据库或者数据源的支持。Flink CDC 下游有丰富的 Connector,例如写入到 TiDB、MySQL、Pg、HBase、Kafka、ClickHouse 等常见的一些系统,也支持各种自定义 connector。
CDC 主要分为基于查询和基于 Binlog 两种方式,我们主要了解一下这两种之间的区别:
骚戴理解:
Batch是批处理,Streaming是流处理,批处理就是一次处理大批数据,流处理就是更新一条数据处理一条数据,其实就是全量和增量
是否可以捕获所有数据变化的解释:假如我有一条数据我更新了很多次,比如我把a改成b后再改成c,然后如果是基于查询的CDC那就只能读取到最后一次更新的数据,只能知道c,而b不能知道,但是如果是基于Binlog的CDC的话就可以知道所有的变化
增加数据库压力:Binlog是日志文件,所以基于Binlog的CDC是不增加数据库压力的
1.3 Flink-CDC
Flink 社区开发了 flink-cdc-connectors 组件,这是一个可以直接从 MySQL、PostgreSQL
等数据库直接读取全量数据和增量变更数据的 source 组件。
ETL 分析中,通过先采集、然后依赖外部 MQ 进行数据投递、在下游消费后进行计算,最后在进行数据存储。整体的数据链路比较长,FlinkCDC 的核心理念在于简化数据链路,底层集成了 Debezium 进行 binlog 的采集、省去了 MQ 部分、最后通过 Flink 进行计算。全链路上都基于 Flink 生态,比较清晰。
1.4 Flink CDC 项目的动机
1. Dynamic Table & ChangeLog Stream
大家都知道 Flink 有两个基础概念:Dynamic Table 和 Changelog Stream。
Dynamic Table 就是 Flink SQL 定义的动态表,动态表和流的概念是对等的。参照上图,流可以转换成动态表,动态表也可以转换成流。
在 Flink SQL中,数据在从一个算子流向另外一个算子时都是以 Changelog Stream 的形式,任意时刻的 Changelog Stream 可以翻译为一个表,也可以翻译为一个流。
联想下 MySQL 中的表和 binlog 日志,就会发现:MySQL 数据库的一张表所有的变更都记录在 binlog 日志中,如果一直对表进行更新,binlog 日志流也一直会追加,数据库中的表就相当于 binlog 日志流在某个时刻点物化的结果;日志流就是将表的变更数据持续捕获的结果。这说明 Flink SQL 的 Dynamic Table 是可以非常自然地表示一张不断变化的 MySQL 数据库表。
在此基础上,我们调研了一些 CDC 技术,最终选择了 Debezium 作为 Flink CDC 的底层采集工具。Debezium 支持全量同步,也支持增量同步,也支持全量 + 增量的同步,非常灵活,同时基于日志的 CDC 技术使得提供 Exactly-Once 成为可能。
将 Flink SQL 的内部数据结构 RowData 和 Debezium 的数据结构进行对比,可以发现两者是非常相似的。
每条 RowData 都有一个元数据 RowKind,包括 4 种类型, 分别是插入 (INSERT)、更新前镜像 (UPDATE_BEFORE)、更新后镜像 (UPDATE_AFTER)、删除 (DELETE),这四种类型和数据库里面的 binlog 概念保持一致。
而 Debezium 的数据结构,也有一个类似的元数据 op 字段, op 字段的取值也有四种,分别是 c、u、d、r,各自对应 create、update、delete、read。对于代表更新操作的 u,其数据部分同时包含了前镜像 (before) 和后镜像 (after)。
通过分析两种数据结构,Flink 和 Debezium 两者的底层数据是可以非常方便地对接起来的,大家可以发现 Flink 做 CDC 从技术上是非常合适的。
2. 传统 CDC ETL 分析
我们来看下传统 CDC 的 ETL 分析链路,如下图所示:
传统的基于 CDC 的 ETL 分析中,数据采集工具是必须的,国外用户常用 Debezium,国内用户常用阿里开源的 Canal,采集工具负责采集数据库的增量数据,一些采集工具也支持同步全量数据。采集到的数据一般输出到消息中间件如 Kafka,然后 Flink 计算引擎再去消费这一部分数据写入到目的端,目的端可以是各种 DB,数据湖,实时数仓和离线数仓。
注意,Flink 提供了 changelog-json format,可以将 changelog 数据写入离线数仓如 Hive / HDFS;对于实时数仓,Flink 支持将 changelog 通过 upsert-kafka connector 直接写入 Kafka。
我们一直在思考是否可以使用 Flink CDC 去替换上图中虚线框内的采集组件和消息队列,从而简化分析链路,降低维护成本。同时更少的组件也意味着数据时效性能够进一步提高。答案是可以的,于是就有了我们基于 Flink CDC 的 ETL 分析流程。
3. 基于 Flink CDC 的 ETL 分析
在使用了 Flink CDC 之后,除了组件更少,维护更方便外,另一个优势是通过 Flink SQL 极大地降低了用户使用门槛,可以看下面的例子:
该例子是通过 Flink CDC 去同步数据库数据并写入到 TiDB,用户直接使用 Flink SQL 创建了产品和订单的 MySQL-CDC 表,然后对数据流进行 JOIN 加工,加工后直接写入到下游数据库。通过一个 Flink SQL 作业就完成了 CDC 的数据分析,加工和同步。
大家会发现这是一个纯 SQL 作业,这意味着只要会 SQL 的 BI,业务线同学都可以完成此类工作。与此同时,用户也可以利用 Flink SQL 提供的丰富语法进行数据清洗、分析、聚合。
而这些能力,对于现有的 CDC 方案来说,进行数据的清洗,分析和聚合是非常困难的。
此外,利用 Flink SQL 双流 JOIN、维表 JOIN、UDTF 语法可以非常容易地完成数据打宽,以及各种业务逻辑加工。
1.5 CDC和Debezium的优缺点
Debezium和Flink CDC都是用于实时数据流处理的开源工具,但它们在设计和功能方面有一些差异。
Debezium的优点
实时数据同步:Debezium基于CDC技术,可以实时捕获数据库中的数据变更,并将其同步到目标系统中。
高可靠性:Debezium支持故障转移和容错机制,当出现故障时,可以自动切换到备用节点上。
易于部署和使用:Debezium提供了丰富的文档和示例,使得用户可以快速地部署和使用。
支持多种数据源:Debezium支持多种主流的关系型数据库,如MySQL、PostgreSQL、MongoDB、SQL Server和Oracle等,同时也支持NoSQL数据库和消息队列等数据源。
可扩展性强:Debezium支持水平扩展,可以轻松地处理大规模的数据变更事件。
生态丰富:Debezium有着广泛的社区支持和活跃的生态系统,例如Kafka Connect、Debezium插件等。
Debezium的缺点
高延迟:Debezium使用CDC技术将数据库中的更改转换为Kafka消息。这会导致一些延迟,并可能影响到实时性要求较高的应用。
复杂性:Debezium需要在源数据库和Kafka之间建立连接和配置,这对于不熟悉Kafka和CDC的人来说可能会很困难。
数据格式限制:由于Debezium使用特定的数据格式,因此需要根据需求对其进行修改或扩展。
稳定性:在某些情况下,Debezium可能会因为网络问题或其他原因导致数据丢失或重复传输。因此,需要进行适当的监控和维护来确保稳定性。
存储成本:由于Debezium将所有更改捕获并发送到Kafka主题,因此需要相应的存储空间来存储所有数据。这可能会增加存储成本。
Flink CDC的优点
实时性:Flink CDC 可以实时捕获和处理数据变化,能够及时反映数据源的最新状态。
精确性:Flink CDC 可以准确地捕获每个数据变化,确保数据的完整性和一致性。
可靠性:Flink CDC 提供了高可靠性的数据处理和容错机制,即使系统出现故障或错误,也能保证数据的安全性和正确性。
灵活性:Flink CDC 支持多种数据源和格式,可以轻松地适应不同的业务场景和需求。
高效性:Flink CDC 使用分布式计算技术,能够快速处理大规模的数据量,并支持流式计算和批量计算两种模式。
Flink CDC的缺点
需要对源数据进行修改:Flink CDC需要在源数据库中创建特殊的日志表或触发器来捕获变更,这可能会影响源系统的性能和稳定性,并且需要对源数据进行修改。
无法保证数据完整性:由于CDC是基于日志或触发器等机制进行数据捕获的,因此在高负载和故障情况下可能会导致数据丢失或不一致。
对网络和存储资源的需求较高:Flink CDC需要大量的网络带宽和存储资源来处理大规模的数据流,并确保数据的及时性和正确性。
需要专业知识:Flink CDC需要相当的专业知识和技能才能正确配置和操作,这可能会增加部署和运维的成本和风险。
Flink CDC和Debezium进行对比
Flink CDC和Debezium都是用于实时数据流处理的工具,但它们的重点略有不同。
Flink CDC是Apache Flink的一部分,主要用于从关系型数据库中捕获变更数据并将其转换为实时数据流。它提供了易于使用的API来快速构建基于流的应用程序,并支持在事件时间和处理时间上进行窗口聚合等高级操作。
与之相比,Debezium是一个独立的开源项目,它专门用于捕获数据库的变更事件并将其转换为Kafka消息。Debezium支持多种数据库引擎,并提供了灵活的配置选项来控制事件的生成和传输。
总的来说,如果您正在构建一个需要从关系型数据库中采集数据的大规模实时流处理系统,那么Flink CDC可能是更好的选择。而如果您只需要将数据库变更事件转换为消息传递到其他系统中,那么Debezium可能更适合您的需求。
1.6 Debezium和Flink CDC有哪些的使用场景
Debezium可用于以下场景
数据库迁移:可以使用Debezium将现有数据库的数据迁移到新的系统中。
数据仓库实时同步:可以使用Debezium捕获源数据库中的变更事件,并将其同步到数据仓库中,以便进行实时分析。
事务日志分析:可以使用Debezium分析数据库的事务日志,以便监控和诊断系统性能问题。
微服务架构中的数据共享:可以使用Debezium将不同微服务之间的数据同步,从而实现数据共享。
消息驱动的应用程序:可以使用Debezium将数据变更事件转换为消息,在消息队列中进行处理。
实时数据集成:可以使用Debezium实现不同系统之间的实时数据集成,例如ERP、CRM等系统之间的数据同步。
Flink CDC(Change Data Capture)可用于以下场景
实时数据同步:可以使用Flink CDC将数据库中的变更事件实时同步到目标系统中,以便进行实时分析和处理。
数据仓库实时同步:可以使用Flink CDC将源数据库中的变更事件同步到数据仓库中,以实现实时数据仓库。
事务日志分析:可以使用Flink CDC分析数据库的事务日志,以便监控和诊断系统性能问题。
增量更新:可以使用Flink CDC对已有的数据进行增量更新,而不是全量重新计算,从而提高计算效率。
数据集成:可以使用Flink CDC将不同系统之间的数据进行实时集成,例如ERP、CRM等系统之间的数据同步。
数据库迁移:可以使用Flink CDC将现有数据库的数据迁移到新的系统中,同时保证数据的一致性。
Flink CDC和Debezium进行使用场景的对比
Flink CDC和Debezium都是用于实现数据变更捕获(CDC)的工具,但是它们的使用场景略有不同。
Flink CDC是Apache Flink的一部分,主要用于构建流处理应用程序。它可以从关系型数据库中捕获变更事件,并将这些事件转换为流数据,然后可以对其进行实时计算和分析。因此,Flink CDC适用于需要实时处理和分析数据的场景,如实时业务智能、监控和警报等。
而Debezium则是一个独立的开源项目,用于连接不同类型的数据源(包括关系型数据库、NoSQL数据库等)并捕获变更事件。它可以将这些事件发送到消息队列或事件总线等目标系统中,以便其他系统消费。因此,Debezium适用于需要将数据变更事件与其他系统集成的场景,如微服务架构、事件驱动架构等。
综上所述,Flink CDC适用于需要实时处理和分析数据的场景,而Debezium适用于需要将数据变更事件与其他系统集成的场景。