Flink CDC
Flink CDC 经过版本迭代,也逐渐进入到大家的视野当中,今天就给大家介绍一下 Flink CDC 是什么以及它早期版本的痛点,当然最重要的是 2.X 版本的迭代内容。
一、Flink CDC 概述
1.1 什么是 Flink CDC
要了解 FlinkCDC 我们首先要知道 CDC 是什么?CDC 是 Change Data Capture 变更数据获取的简称。核心思想就是检测捕获数据库的变动(包括数据或数据表的插入,更新以及删除等),将这些变更按发生的顺序完成记录下来,写入消息中间件中提供给其他的消费者。
而我们的 flink-cdc-connectors 组件,是一个可以直接从 Mysql,PostgreSQL 等数据库中直接读取全量数据和增量变更数据的 source 组件。而它的研发主要是来自阿里云开源大数据团队核心成员云邪。
1.2 为什么要使用 Flink CDC
传统的 CDC 流式分析图
经过整个链路我们可以看到刚开始数据进入到 Kafka 一定要有数据采集工具的参与,我们国内主要使用阿里的 Cannal 去采集数据库的 binlog 文件,国外常用的是 Debezium。采集到之后我们将数据输入到 Kafka 然后 Flink 再进行消费计算输入到目的地。
这时候我们就可以思考,flink 的本质就是灵活就是快,毫秒级,但是整个数据链路不仅仅只有 flink,所以为了更快更便捷,我们可以用 Flink CDC 来代替中间虚线框内的两大组件。还有一个关键的因素就是可以减少用户的学习成本和使用成本。
Flink-CDC 的流式分析图
通过上图我们可以清晰地看到,在图 1-1 中出现的虚线框中的部分已经被取代,由此可以看出 Flink-CDC 的特点就是数据链路的优化以及数据的时效性。
1.3 Flink CDC 1.x 的痛点
我们知道在全量和增量同步的情况下需要保证数据的一致性,而要保证数据的一致性就得加锁进行保证。底层 Debezium 在保证数据一致性时需要对读取的库或者表加锁,但全局锁可能导致数据库锁住,表级锁会锁住表的读,而我们整个业务数据都在其中,这个是非常危险的,DBA 一般也不会给权限。
当然,也不支持水平增加扩展,因为早期是基于 Debezium,架构只有 1 个节点,所以导致只支持单并发。如果在全量读取阶段这个表是很大的(亿级别),读取的时间要在几个小时,这个时间有点过长,而对于我们用户而言肯定是希望能够水平的进行扩展,就像 Hadoop 的 Mapreduce 能够根据切片的个数并行地运行多个 map 任务一样,希望能够通过支持水平扩展的方式来提升我们的作业速度。
在全量读取的阶段是不支持 checkpoint 的,这个时候就会产生一个很大的问题,当我们有一个全量同步的任务,这个任务需要 8 个小时,但是在第 7 小时 59 分时它挂掉了,这时候就需要重新进行读取。
二、Flink CDC 2.0 详解
2.1 Flink CDC 2.x
如今的 flink2.0 要克服的困难首先就是要支持无锁,支持水平扩展,支持 checkpoint。
整体概览
在对有主键的表做初始化模式时,整体的流程主要分为 5 个阶段:
Chunk 切分;
Chunk 分配(全量)。将数据切分成一小块一小块,切分好后分配给不同的 slot 进行运行(并行), (实现并行 & CheckPoint)各自做 CheckPoint;
Chunk 读取。(实现无锁读取)分配完成之后要读取数据,这个过程是无锁读取;
Chunk 汇报。向上游汇报自己的 CheckPoint 已经完成了,收集完成之后启动增量的数据;
Chunk 分配(增量)。最后读取最新的 binlog 日志所做的分配,也就是增量任务开始。
切分
对目标数据,按照主键进行数据的分片。chunk 的切分其实和很多数据库的分库分表原理类似,一张表有主键我们可以按照主键对数据进行分片,设置每个切片的区间是左闭右开或者左开右闭来保证数据的连续性。
2.2 Chunk 分配
Chunk 划分好之后就开始分配给 SourceReader,因为 SourceReader 有多个所以就实现了并行读取的功能。而且每个 Chunk 在读取的时候可以自己做 CheckPoint,就算某个 Chunk 执行失败了也不用再重头开始进行。
如果每个 SourceReader 保证了数据的一致性,则全表就一定保证了数据的一致性。
2.3 Chunk 读取
因为在读取的过程中可能会有一些增量的变化。我们会有一个高位点和低位点,如图所示当前 Chunk 所在的区间 K1-K10,我们先将这个区间 select 出来存在 window buffer 里面,在 select 之前我们保存一下 binlog 的位置叫做低位点,在 select 之后我们再保存一下 binlog 的位置叫做高位点。而增量的部分就是低位点到高位点之间,我们再根据主键对我们 Window buffer 里面的数据进行修正输出。
上面保证的是单个 chunk 的一致性读。
但是如果我们有多个表分了很多不同的 chunk,这些 chunk 都分布在不同的地方,那如何保证一致性读呢?在图 2-2 中我们可以看到有 SourceEnumerator 的组件,这个组件主要用于划分 Chunk,划分好的 Chunk 会提供给下游的 SourceReader 去读取,通过把 Chunk 分发给不同的 SourceReader 便实现了并发读取 Snapshot Chunk 的目的。
2.4 Chunk 汇报
汇报的主要目的是为了方便我们后续读取 binlog。因为我们支持的是全量和增量,当我们全量消费完成之后只需要消费增量的 binlog 即可。
2.5 Chunk 分配
FlinkCDC 这个 chunk 的分配主要是为了消费增量的 binlog。此时是通过下发 Binlog Chunk 给任意一个 SourceReader 进行单并发读取来实现的。
总述:
我们可以整理一下这个整体的流程:我们先是通过主键对这个表进行分片,分片之后分配给不同的 SourceRead 去读取数据,先读取全量的数据,再读取增量的数据。类似 flink 的全量窗口后面加上了一个允许迟到的时间,当水印到达窗口的关闭时间时窗口会触发计算,后续在迟到时间之内再来的数据以增量计算的方式进行处理。
好了,以上就是本篇的全部内容了,希望通过对 Flink CDC 早期 1.X 痛点的描述,以及 2.X 这些痛点的改进方案介绍,能让大家对它有更多的了解和认识。
本期内容就到这里了,如果喜欢就点个关注吧,微信公众号搜索“数 新 网 络 科 技 号”可查看更多精彩内容~
版权声明: 本文为 InfoQ 作者【数新网络官方账号】的原创文章。
原文链接:【http://xie.infoq.cn/article/22f574f060948f1357dbd1a19】。文章转载请联系作者。
评论