FlinkCDC20正式发布,详解核心

一、CDC概述

CDC的全称是ChangeDataCapture,在广义的概念上,只要是能捕获数据变更的技术,我们都可以称之为CDC。目前通常描述的CDC技术主要面向数据库的变更,是一种用于捕获数据库中数据变更的技术。CDC技术的应用场景非常广泛:

数据同步:用于备份,容灾;数据分发:一个数据源分发给多个下游系统;数据采集:面向数据仓库/数据湖的ETL数据集成,是非常重要的数据源。

CDC的技术方案非常多,目前业界主流的实现机制可以分为两种:

基于查询的CDC:离线调度查询作业,批处理。把一张表同步到其他系统,每次通过查询去获取表中最新的数据;无法保障数据一致性,查的过程中有可能数据已经发生了多次变更;不保障实时性,基于离线调度存在天然的延迟。基于日志的CDC:实时消费日志,流处理,例如MySQL的binlog日志完整记录了数据库中的变更,可以把binlog文件当作流的数据源;保障数据一致性,因为binlog文件包含了所有历史变更明细;保障实时性,因为类似binlog的日志文件是可以流式消费的,提供的是实时数据。

对比常见的开源CDC方案,我们可以发现:

对比增量同步能力,基于日志的方式,可以很好的做到增量同步;而基于查询的方式是很难做到增量同步的。对比全量同步能力,基于查询或者日志的CDC方案基本都支持,除了Canal。而对比全量+增量同步的能力,只有FlinkCDC、Debezium、OracleGoldengate支持较好。从架构角度去看,该表将架构分为单机和分布式,这里的分布式架构不单纯体现在数据读取能力的水平扩展上,更重要的是在大数据场景下分布式系统接入能力。例如FlinkCDC的数据入湖或者入仓的时候,下游通常是分布式的系统,如Hive、HDFS、Iceberg、Hudi等,那么从对接入分布式系统能力上看,FlinkCDC的架构能够很好地接入此类系统。在数据转换/数据清洗能力上,当数据进入到CDC工具的时候是否能较方便的对数据做一些过滤或者清洗,甚至聚合?在FlinkCDC上操作相当简单,可以通过FlinkSQL去操作这些数据;但是像DataX、Debezium等则需要通过脚本或者模板去做,所以用户的使用门槛会比较高。另外,在生态方面,这里指的是下游的一些数据库或者数据源的支持。FlinkCDC下游有丰富的Connector,例如写入到TiDB、MySQL、Pg、HBase、Kafka、ClickHouse等常见的一些系统,也支持各种自定义connector。

二、FlinkCDC项目

讲到这里,先带大家回顾下开发FlinkCDC项目的动机。

1.DynamicTableChangeLogStream

大家都知道Flink有两个基础概念:DynamicTable和ChangelogStream。

DynamicTable就是FlinkSQL定义的动态表,动态表和流的概念是对等的。参照上图,流可以转换成动态表,动态表也可以转换成流。在FlinkSQL中,数据在从一个算子流向另外一个算子时都是以ChangelogStream的形式,任意时刻的ChangelogStream可以翻译为一个表,也可以翻译为一个流。

联想下MySQL中的表和binlog日志,就会发现:MySQL数据库的一张表所有的变更都记录在binlog日志中,如果一直对表进行更新,binlog日志流也一直会追加,数据库中的表就相当于binlog日志流在某个时刻点物化的结果;日志流就是将表的变更数据持续捕获的结果。这说明FlinkSQL的DynamicTable是可以非常自然地表示一张不断变化的MySQL数据库表。

在此基础上,我们调研了一些CDC技术,最终选择了Debezium作为FlinkCDC的底层采集工具。Debezium支持全量同步,也支持增量同步,也支持全量+增量的同步,非常灵活,同时基于日志的CDC技术使得提供Exactly-Once成为可能。

将FlinkSQL的内部数据结构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.传统CDCETL分析

我们来看下传统CDC的ETL分析链路,如下图所示:

传统的基于CDC的ETL分析中,数据采集工具是必须的,国外用户常用Debezium,国内用户常用阿里开源的Canal,采集工具负责采集数据库的增量数据,一些采集工具也支持同步全量数据。采集到的数据一般输出到消息中间件如Kafka,然后Flink计算引擎再去消费这一部分数据写入到目的端,目的端可以是各种DB,数据湖,实时数仓和离线数仓。

注意,Flink提供了changelog-jsonformat,可以将changelog数据写入离线数仓如Hive/HDFS;对于实时数仓,Flink支持将changelog通过upsert-kafkaconnector直接写入Kafka。

我们一直在思考是否可以使用FlinkCDC去替换上图中虚线框内的采集组件和消息队列,从而简化分析链路,降低维护成本。同时更少的组件也意味着数据时效性能够进一步提高。答案是可以的,于是就有了我们基于FlinkCDC的ETL分析流程。

3.基于FlinkCDC的ETL分析

在使用了FlinkCDC之后,除了组件更少,维护更方便外,另一个优势是通过FlinkSQL极大地降低了用户使用门槛,可以看下面的例子:

该例子是通过FlinkCDC去同步数据库数据并写入到TiDB,用户直接使用FlinkSQL创建了产品和订单的MySQL-CDC表,然后对数据流进行JOIN加工,加工后直接写入到下游数据库。通过一个FlinkSQL作业就完成了CDC的数据分析,加工和同步。

大家会发现这是一个纯SQL作业,这意味着只要会SQL的BI,业务线同学都可以完成此类工作。与此同时,用户也可以利用FlinkSQL提供的丰富语法进行数据清洗、分析、聚合。

而这些能力,对于现有的CDC方案来说,进行数据的清洗,分析和聚合是非常困难的。

此外,利用FlinkSQL双流JOIN、维表JOIN、UDTF语法可以非常容易地完成数据打宽,以及各种业务逻辑加工。

4.FlinkCDC项目发展

年7月由云邪提交了第一个


转载请注明:http://www.aierlanlan.com/grrz/2757.html