【科普小文】3分钟搞懂 Apache SeaTunnel CDC 数据同步

2024-04-08 19:52

本文主要是介绍【科普小文】3分钟搞懂 Apache SeaTunnel CDC 数据同步,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

CDC简介

CDC(Change Data Capture)是一种用于跟踪数据库库变更事件(插入、更新、删除)中的行级更改,并将事件以发生的顺序通知到其他系统处理。在容灾场景下,CDC主要实现的是主备间的数据同步,即从主数据库到备数据库的数据实时同步。

file

source ----------> CDC ----------> sink

Apache SeaTunne CDC

SeaTunnel CDC的数据同步分为两种:

  • 快照读:读取表的历史数据

  • 增量跟踪:读取表的增量日志更改数据

2.1 无锁快照同步

无锁快照同步阶段,为什么强调无锁,是因为现有的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的位置,用于后续的校对

2.2 增量同步

增量同步阶段是基于上述快照读取阶段后,在源数据库发生变化时,实时将变更的数据同步到备数据库,不同的是,此阶段监听的是数据库的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?

3.1 快照读阶段

在快照读阶段,例如某个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               vbin log --|---------------------------------------------------|-- log offsetlow watermark                                     high watermarkCDC读到的数据: 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 offsetmin 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等节点都会保存自己的内存状态。

本文由 白鲸开源科技 提供发布支持!

这篇关于【科普小文】3分钟搞懂 Apache SeaTunnel CDC 数据同步的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/886350

相关文章

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

python实现对数据公钥加密与私钥解密

《python实现对数据公钥加密与私钥解密》这篇文章主要为大家详细介绍了如何使用python实现对数据公钥加密与私钥解密,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录公钥私钥的生成使用公钥加密使用私钥解密公钥私钥的生成这一部分,使用python生成公钥与私钥,然后保存在两个文

mysql中的数据目录用法及说明

《mysql中的数据目录用法及说明》:本文主要介绍mysql中的数据目录用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、版本3、数据目录4、总结1、背景安装mysql之后,在安装目录下会有一个data目录,我们创建的数据库、创建的表、插入的

Navicat数据表的数据添加,删除及使用sql完成数据的添加过程

《Navicat数据表的数据添加,删除及使用sql完成数据的添加过程》:本文主要介绍Navicat数据表的数据添加,删除及使用sql完成数据的添加过程,具有很好的参考价值,希望对大家有所帮助,如有... 目录Navicat数据表数据添加,删除及使用sql完成数据添加选中操作的表则出现如下界面,查看左下角从左

SpringBoot中4种数据水平分片策略

《SpringBoot中4种数据水平分片策略》数据水平分片作为一种水平扩展策略,通过将数据分散到多个物理节点上,有效解决了存储容量和性能瓶颈问题,下面小编就来和大家分享4种数据分片策略吧... 目录一、前言二、哈希分片2.1 原理2.2 SpringBoot实现2.3 优缺点分析2.4 适用场景三、范围分片

Redis分片集群、数据读写规则问题小结

《Redis分片集群、数据读写规则问题小结》本文介绍了Redis分片集群的原理,通过数据分片和哈希槽机制解决单机内存限制与写瓶颈问题,实现分布式存储和高并发处理,但存在通信开销大、维护复杂及对事务支持... 目录一、分片集群解android决的问题二、分片集群图解 分片集群特征如何解决的上述问题?(与哨兵模

浅析如何保证MySQL与Redis数据一致性

《浅析如何保证MySQL与Redis数据一致性》在互联网应用中,MySQL作为持久化存储引擎,Redis作为高性能缓存层,两者的组合能有效提升系统性能,下面我们来看看如何保证两者的数据一致性吧... 目录一、数据不一致性的根源1.1 典型不一致场景1.2 关键矛盾点二、一致性保障策略2.1 基础策略:更新数

Oracle 数据库数据操作如何精通 INSERT, UPDATE, DELETE

《Oracle数据库数据操作如何精通INSERT,UPDATE,DELETE》在Oracle数据库中,对表内数据进行增加、修改和删除操作是通过数据操作语言来完成的,下面给大家介绍Oracle数... 目录思维导图一、插入数据 (INSERT)1.1 插入单行数据,指定所有列的值语法:1.2 插入单行数据,指

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal