【科普小文】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

相关文章

Debezium 与 Apache Kafka 的集成方式步骤详解

《Debezium与ApacheKafka的集成方式步骤详解》本文详细介绍了如何将Debezium与ApacheKafka集成,包括集成概述、步骤、注意事项等,通过KafkaConnect,D... 目录一、集成概述二、集成步骤1. 准备 Kafka 环境2. 配置 Kafka Connect3. 安装 D

Redis的数据过期策略和数据淘汰策略

《Redis的数据过期策略和数据淘汰策略》本文主要介绍了Redis的数据过期策略和数据淘汰策略,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录一、数据过期策略1、惰性删除2、定期删除二、数据淘汰策略1、数据淘汰策略概念2、8种数据淘汰策略

轻松上手MYSQL之JSON函数实现高效数据查询与操作

《轻松上手MYSQL之JSON函数实现高效数据查询与操作》:本文主要介绍轻松上手MYSQL之JSON函数实现高效数据查询与操作的相关资料,MySQL提供了多个JSON函数,用于处理和查询JSON数... 目录一、jsON_EXTRACT 提取指定数据二、JSON_UNQUOTE 取消双引号三、JSON_KE

Python给Excel写入数据的四种方法小结

《Python给Excel写入数据的四种方法小结》本文主要介绍了Python给Excel写入数据的四种方法小结,包含openpyxl库、xlsxwriter库、pandas库和win32com库,具有... 目录1. 使用 openpyxl 库2. 使用 xlsxwriter 库3. 使用 pandas 库

SpringBoot定制JSON响应数据的实现

《SpringBoot定制JSON响应数据的实现》本文主要介绍了SpringBoot定制JSON响应数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们... 目录前言一、如何使用@jsonView这个注解?二、应用场景三、实战案例注解方式编程方式总结 前言

使用Python在Excel中创建和取消数据分组

《使用Python在Excel中创建和取消数据分组》Excel中的分组是一种通过添加层级结构将相邻行或列组织在一起的功能,当分组完成后,用户可以通过折叠或展开数据组来简化数据视图,这篇博客将介绍如何使... 目录引言使用工具python在Excel中创建行和列分组Python在Excel中创建嵌套分组Pyt

在Rust中要用Struct和Enum组织数据的原因解析

《在Rust中要用Struct和Enum组织数据的原因解析》在Rust中,Struct和Enum是组织数据的核心工具,Struct用于将相关字段封装为单一实体,便于管理和扩展,Enum用于明确定义所有... 目录为什么在Rust中要用Struct和Enum组织数据?一、使用struct组织数据:将相关字段绑

在Mysql环境下对数据进行增删改查的操作方法

《在Mysql环境下对数据进行增删改查的操作方法》本文介绍了在MySQL环境下对数据进行增删改查的基本操作,包括插入数据、修改数据、删除数据、数据查询(基本查询、连接查询、聚合函数查询、子查询)等,并... 目录一、插入数据:二、修改数据:三、删除数据:1、delete from 表名;2、truncate

Java实现Elasticsearch查询当前索引全部数据的完整代码

《Java实现Elasticsearch查询当前索引全部数据的完整代码》:本文主要介绍如何在Java中实现查询Elasticsearch索引中指定条件下的全部数据,通过设置滚动查询参数(scrol... 目录需求背景通常情况Java 实现查询 Elasticsearch 全部数据写在最后需求背景通常情况下

深入理解Apache Airflow 调度器(最新推荐)

《深入理解ApacheAirflow调度器(最新推荐)》ApacheAirflow调度器是数据管道管理系统的关键组件,负责编排dag中任务的执行,通过理解调度器的角色和工作方式,正确配置调度器,并... 目录什么是Airflow 调度器?Airflow 调度器工作机制配置Airflow调度器调优及优化建议最