一文搞懂 CDC(Change Data Capture)同步原理解析
CDC简介
CDC(Change Data Capture)是一种用于跟踪数据库库变更事件(插入、更新、删除)中的行级更改,并将事件以发生的顺序通知到其他系统处理。在容灾场景下,CDC主要实现的是主备间的数据同步,即从主数据库到备数据库的数据实时同步。
source ----------> CDC ----------> sink
Apache SeaTunne CDC
SeaTunnel CDC的数据同步分为两种:
-
快照读:读取表的历史数据
-
增量跟踪:读取表的增量日志更改数据
无锁快照同步
无锁快照同步阶段,为什么强调无锁,是因为现有的CDC平台在进行历史数据的同步时可能会进行锁表操作,例如Debezium。快照读阶段就是对数据库的历史数据库进行同步的过程,其基本概述流程如下:
storage------------->splitEnumerator----------split---------->reader ^ | | | \-----------------report------------/
Split划分
splitEnumerator
(split分发器)按照指定的字段(例如表id或唯一键)和步长将表数据划分为多个分片split。
并行处理
每个split通过路由算法分配给不同的reader进行并行读取,一个reader会占用一个连接。
事件反馈
每个reader完成split读取后会向splitEnumerator
报告进度。splitEnumerator
会发送给reader一个分片,分片的元数据信息如下:
String splitId 路由id TableId tableId 表id SeatunnelRowType splitKeyType 分片基于的字段的类型 Object splitStart 分片读取起点 Object splitEnd 分片读取终点
reader收到split信息后会生成相关的sql语句,在此之前会记录当前split对应到数据库日志log的开始位置,等处理完当前split后上报report给splitEnumerator
,report内容如下:
String splitId 分片id Offset highWatermark 分片对应log的位置,用于后续的校对
增量同步
增量同步阶段是基于上述快照读取阶段后,在源数据库发生变化时,实时将变更的数据同步到备数据库,不同的是,此阶段监听的是数据库的log日志,例如mysql的bin log。增量跟踪通常是单线程处理,这样可以避免重复拉取bin log,减轻对数据库的压力,因此该阶段只有一个reader工作,只占用一个连接。
data log------------->splitEnumerator----------split---------->reader ^ | | | \-----------------report------------/
增量同步会合成快照阶段所有split、table,因此只会存在一个split,增量同步阶段的split信息如下:
String splitId Offset startingOffset 所有split中最小的log start Offset endingOffset log的结束位置,若无则代表是持续的,例如增量阶段 List<TableId> tableIds Map<TableId, Offset> tanleWatermarks 所有split的watermark List<CompletedSnapshotSplitInfo> completedSnapshotSplitInfos 快照阶段读取的split细节信息
其中CompletedSnapshotSplitInfo的具体字段如下:
String splitId TableId tableId SeatunnelRowType splitKeyType Object splitStart Object splitEnd Offset watermark 对应了report中的highWatermark
增量阶段的split包含了快照阶段所有split的watermark,会去从其中选出一个合适的位置进行增量同步,这个合适位置就是最小的watermark。
Exactly-once
无论是快照读还是增量读,同步的过程中数据库可能也在经历变化,如何保证exactly-once?
快照读阶段
在快照读阶段,例如某个split在同步的过程中,这段split中的数据发生了变换,例如下图操作,插入一条k3,更新k2,删除k1,如果在读的过程中不做任务标识,那么这部分的更新信息就会丢失,seatunnel的做法是:
在Split读取之前首先去数据库查一下bin log位置:low watermark
读取split{start, end}
数据
再记录一下高水位high watermark
如果high = low 说明在读取该split期间,该split的数据没有发生变化;
如果(high - low) > 0,说明在处理的过程中发生了数据变化,会进行如下操作:
- 将读到的split数据在内存中建立内存表缓存;
- 将low watermark~high watermark的变更;
- 按顺序、主键重放操作到内存表
报告report high watermark
insert k3 update k2 delete k1 | | | v v v bin log --|---------------------------------------------------|-- log offset low watermark high watermark CDC读到的数据: k1 k3 k4 | 重放 v 真实的数据: k2 k3' k4
增量阶段
在增量阶段开始之前首先会对上一个步骤的所有split做校验,因为在split和split之间的间隙也有可能出现数据更新,例如在split1和split2之间插入了若干条记录,在快照阶段就会遗漏掉,对于这种split之间的数据回捞,SeaTunnel的做法是:
从所有的split的report中找到最小的watermark,作为start watermark,开始读取log。
每读一条log都去completedSnapshotSplitInfos
中找该条数据是否在某个split被处理过了,如果没有被处理过,说明是split间隙数据,应该被重新修正。
当表过滤完后,可以从completedSnapshotSplitInfos
中删除,继续处理剩余的表。
直到所有的split都校验结束,就进入到了完全的增量阶段。
|------------filter split2-----------------| |----filter split1------| data log -|-----------------------|------------------|----------------------------------|- log offset min watermark split1 watermark split2 watermark max watermark
断点续传
如果做到暂停恢复?分布式快照算法(Chandy-Lamport):
假设系统中包含了两个进程p1和p2,p1进程状态包含三个变量X1 Y1 Z1,p2包含了三个变量X2 Y2 Z2,初始状态如下:
p1 p2 X1:0 X2:4 Y1:0 Y2:2 Z1:0 Z2:3
此时由p1发起全局snapshot记录,p1先记录本身的进程状态,然后向p2发送marker信息。
在marker信息到达p2之前,p2向p1发送message M。
p1 p2 X1:0 -------marker-------> X2:4 Y1:0 <---------M---------- Y2:2 Z1:0 Z2:3
p2收到p1发送来的Marker信息后,记录自己的状态,然后p1收到p2之前发送来的Message M,由于p1已经做了Local snapshot了,所以p1只需要记录M,所以最终的snapshot如下:
p1 M p2 X1:0 X2:4 Y1:0 Y2:2 Z1:0 Z2:3
在SeaTunnel CDC的过程中,Marker同发送给所有的Reader、SplitEnumerator、Writer等节点都会保存自己的内存状态。
本文由 白鲸开源科技 提供发布支持!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
DeepSeek 模型快速体验,魔搭+函数计算一键部署模型上云
DeepSeek 模型近期在全网引发了广泛关注,热度持续攀升。其开源模型 DeepSeek-V3 和 DeepSeek-R1 在多个基准测试中表现优异,在数学、代码和自然语言推理任务上,性能与 OpenAI 的顶尖模型相当。对于期待第一时间在本地进行使用的用户来说,尽管 DeepSeek提供了从1.5B到70B参数的多尺寸蒸馏模型,但本地部署仍需要一定的技术门槛。对于资源有限的用户进一步使用仍有难点。 为了让更多开发者第一时间体验 DeepSeek 模型的魅力,Modelscope 社区 DeepSeek-R1-Distill-Qwen模型现已支持一键部署(SwingDeploy)上函数计算 FC 服务,欢迎开发者立即体验。 魔搭+函数计算,一键部署模型上云 SwingDeploy 是魔搭社区推出的模型一键部署服务,支持将魔搭上的各种(包括语音,视频,NLP等不同领域)模型直接部署到用户指定的云资源上,比如函数计算FC(以下简称FC)GPU算力实例。本文介绍如何通过魔搭SwingDeploy服务,快速将DeepSeek模型部署到阿里云函数计算FC平台的闲置GPU实例,并对部署后的模型进...
- 下一篇
面向 Workload 级别的灵活可配置 Serverless 弹性解决方案
Serverless 是云计算的进一步延伸,因此其继承了云计算的最大特点,即按需弹性伸缩。这样的模型设计让开发者无需关注具体的部署资源,充分利用资源规模效应,提供更好的弹性能力,也能让企业切实享受到真正的按需使用特征。正因如此,更多的云厂商们不约而同地转向 Serverless 这一新的架构设计理念。 "灵活可配置"作为 Serverless 技术的弹性核心能力之一,所关注的是"通过简单、少侵入、灵活可配置的方法让具体用云场景能充分使用弹性资源"。其本质是解决了容量规划与实际集群负载配置间的矛盾。本文将依次介绍 ElasticWorkload [ 1] 、WorkloadSpread [ 2] 、UnitedDeployment [ 3] 和 ResourcePolicy [ 4] 这四种资源可配置插件,详细探讨它们的核心能力、技术原理与优劣势,以及在真实场景中的应用。通过这些内容分享阿里云容器服务在应对 Serverless 负载弹性问题时的技术演进和思考。 弹性场景概述 随着 Serverless 技术的成熟,越来越多企业倾向于使用弹性资源(如 ACS 等 Serverless 容...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2全家桶,快速入门学习开发网站教程
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- 2048小游戏-低调大师作品
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS6,CentOS7官方镜像安装Oracle11G
- CentOS关闭SELinux安全模块