Flink CDC 2.0 设计方案

本文介绍了Flink CDC 2.0的设计方案,着重讨论了无锁算法如何解决传统数据同步的加锁问题,以及全量+增量同步的并发设计。Flink CDC通过采用无锁设计和基于FLIP-27的Source实现,提升了数据一致性与系统扩展性,旨在简化数据同步流程,减少维护成本。未来规划包括稳定性优化、资源分配策略改进和更多数据库及格式的支持。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

译者前语:最近看到徐榜江老师在北京分享的CDC2.0架构改进,看到后我就立刻及时更进,时至一年,CDC有哪些变化我自己也比较好奇,于是和社区主动申请翻译了这篇文章,学习之余也有助于自己更加了解Flink CDC 机制。转载文章至其他地方请注明出处和作者,感谢各位~

文章介绍:如何将数据库中的数据接入数据仓库/数据湖是数仓建设需要考虑的关键一环。今天就由来自阿里的徐榜江(雪尽)老师带来的分享Flink-CDC 2.0 设计方案。徐榜江(雪尽)老师就职于阿里巴巴,目前主要担任FlinkSQL的研发工作。今天带来的Flink-CDC 2.0 设计方案,首先先会对CDC进行简单的概述和解决场景描述,相对比于传统数据同步方案,Flink-CDC 数据同步方案的优缺点进行简单概括,同时分析 Flink-CDC 架构的优势详细解读无锁设计和全量阶段并发设计以及CDC后续的一些规划本次分享

作者:徐榜江(雪尽)(Apache Flink Contributor,阿里巴巴高级开发工程师)
整理:陈政羽(Apache Flink China 社区志愿者)

CDC概述

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

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

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

基于查询的 CDC

  • 离线调度查询作业,批处理。把一张表同步到其他系统,每次通过查询去获取查询的结果

  • 无法保障数据一致性,查的过程中有可能数据已经发生了多次变更

  • 不保障实时性,基于离线调度有查询延迟

基于日志的 CDC

  • 实时消费日志,流处理,例如MYSQL的BINLOG完整记录库里面的变更,可以把BINLOG当作流的数据源
  • 保障数据一致性,因为BINLOG所有的历史明细都可以获得
  • 提供实时数据,因为提供是流式的消费方式,所以实时性有爆炸

常用开源CDC比较
请添加图片描述
通过图上对比我们可以看到,对于日志查询的方式,增量同步都可以做到,但是基于查询的同步是无法做到增量同步的;在断点续传中,我们的任务有可能消费数据到某个时刻点上面因为各种原因而中断导致任务失败,后面恢复作业的时候我们需要基于这个位移点进行恢复的一个功能。在日志同步功能上;在全量同步上,基于查询或者日志都可以做到,例如MYSQL可以把BINLOG进行重放或者直接整库同步,但是Canal没有做全量支持;在全量+增量的模式上,Flink CDC、Debezium、Oracle Goldengate都支持;在架构角度去看,可以分为单机和分布式,分布式我们不单纯表现在水平扩展上面,在大数据场景会影响比较大,例如我们的数据需要入湖或者入仓,我们的文件系统例如HDFS是分布式架构,在对接上面是否能有比较好的支持,从这个角度上面上看Flink CDC 会支持比较好;数据转换方面,当我们数据进入到CDC 工具时候是否能比较方便的对数据做一些过滤或者清洗,在Flink CDC 上面会比较简单操作,可以通过Flink SQL 去操作这些数据,但是例如像DataX、Debezium需要通过脚本或者模板去做,所以用户在使用的门槛会比较高;生态方面指的是下游的一些数据库或者数据源支持,例如像Flink CDC 下游有丰富的Connector,像写入到TiDB、MySQL、HBase、Kafka等常见的一些组件。

Flink CDC 项目

先来回顾2个基础概念:Dynamic Table 和 Change Log Stream

请添加图片描述
请添加图片描述Dynamic Table 就是 Flink 内部定义的表,它是和一条

目前官方尚未发布 Apache Flink 2.0 的正式版本,因此关于 Flink 2.0 的具体示例代码和实例教程较少公开可用。然而,可以根据现有 Flink 版本的功能推测其未来可能的方向,并结合已有的功能提供一些通用的示例。 以下是基于当前 Flink 功能的一个典型数据流处理示例: ### 数据流处理示例 假设有一个股票价格流 `stockPriceStream`,我们需要对其进行按符号 (`symbol`) 分组并计算每分钟的最大价格。 ```scala import org.apache.flink.api.common.functions.AggregateFunction import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment import org.apache.flink.streaming.api.windowing.time.Time import org.apache.flink.streaming.api.datastream.DataStream import org.apache.flink.streaming.api.scala._ case class StockPrice(symbol: String, price: Double) object StockMaxPrice { def main(args: Array[String]): Unit = { val env = StreamExecutionEnvironment.getExecutionEnvironment // 原始股票价格流 val stockPriceRawStream: DataStream[StockPrice] = ??? // 按照 symbol 进行 keyBy 分组 val keyedStream = stockPriceRawStream.keyBy(_.symbol)[^2] // 计算每分钟最大价格 val maxPricesPerMinute = keyedStream .timeWindow(Time.minutes(1)) .aggregate(new MaxPriceAggregate()) maxPricesPerMinute.print() env.execute("Flink Streaming Scala API Example") } // 自定义聚合函数用于计算最大价格 class MaxPriceAggregate extends AggregateFunction[StockPrice, Double, Double] { override def createAccumulator(): Double = Double.MinValue override def add(value: StockPrice, accumulator: Double): Double = Math.max(accumulator, value.price) override def getResult(accumulator: Double): Double = accumulator override def merge(a: Double, b: Double): Double = Math.max(a, b) } } ``` 此代码展示了如何使用 Flink 对股票价格流进行分组、窗口化以及聚合操作。其中的关键概念包括 `keyBy` 和时间窗口的应用。 --- ### 关于 Flink Connector 如果需要连接外部系统(如 Kafka 或数据库),可以利用 Flink 提供的各种内置 connector。例如,以下是一个简单的 Kafka Source 示例: ```java import org.apache.flink.api.common.serialization.SimpleStringSchema; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.connector.kafka.source.KafkaSource; public class KafkaExample { public static void main(String[] args) throws Exception { final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); KafkaSource<String> kafkaSource = KafkaSource.<String>builder() .setBootstrapServers("localhost:9092") .setTopics("input-topic") .setGroupId("test-group") .setValueOnlyDeserializer(new SimpleStringSchema()) .build(); env.fromSource(kafkaSource, WatermarkStrategy.noWatermarks(), "Kafka Source") .print(); env.execute("Flink Kafka Example"); } } ``` 上述代码片段展示了一个基本的 Kafka 数据源配置过程[^1]。 --- ### 性能优化与事务支持 Flink 支持高性能的流处理能力,具有高吞吐量、低延迟等特点[^3]。此外,在涉及事务处理时,可以通过 `transaction` 字段传递额外信息以增强系统的可靠性[^4]。 尽管这些特性并非特定针对 Flink 2.0 设计,但它们代表了现代流处理框架的核心需求和发展方向。 --- ####
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值