首页 > 其他分享 >TiCDC核心原理解析

TiCDC核心原理解析

时间:2023-12-18 14:02:36浏览次数:29  
标签:Capture 同步 任务 集群 TiCDC Owner 原理 解析

作者: Jellybean



架构简介



基本架构

TiCDC核心原理解析_存储空间

TiCDC 集群由多个对等节点组成,是一种分布式无状态的架构设计。当 TiDB 集群内部有数据变更的时候,就会产生 KV change log。

KV change log 是 TiKV 提供的隐藏大部分内部实现细节的的 row changed event,TiCDC 会实时从 TiKV 拉取这些 Event 完成扫描和拼装,再同步到下游节点。同步任务将会按照一定的调度规则被划分给一个或者多个 Capture 处理。

为了方便深入了解 Capture 的执行过程,需要理解一些概念:

  • Owner
  • 可以理解为是 TiCDC 集群的 leader 节点,它负责响应用户的请求、调度集群和同步 DDL 等任务。
  • Processor
  • Capture 内部的逻辑线程,一个 Capture 节点中可以运行多个 Processor。
  • Table Pipeline
  • Processor 内部的数据同步管道,每个 TablePipeline 负责处理一张表,表的数据会在这个管道中处理和流转,最后被发送到下游。
  • Changefeed
  • 是由用户启动同步任务,一个同步任务中可能包含多张表,这些表会被 Owner 划分为多个子任务分配到不同的 Capture 进行处理。每个 Processor 负责处理 ChangeFeed 的一个子任务。


执行流程

内部详细的执行过程如下图:

TiCDC核心原理解析_存储空间_02

TiCDC 的 DML 同步流和 DDL 同步流是分开的。从上面的架构图中可以看到, DML 的同步是由 Processor 进行的,数据流从上游的 TiKV 流入经过 Processor 内的 TablePipeline ,最后被同步到下游。而 DDL 同步则是由 Owner 进行的,OwnerDDLPuller 拉取上游发生的 DDL 事件,然后在内部经过一系列的处理之后,通过 DDLSink 同步到下游。

  • OwnerSchemaStorage:由 Owner 持有,维护了当前所有表最新的 schema 信息,这些表的 schema 信息主要会被 scheduler 所使用,用来感知同步任务的表数量的变化;此外,还会被 owner 用来解析 ddlPuller 拉取到的 DDL 事件。
  • ProcessorSchemaStorage:由 Processor 持有,维护了当前所有表的多个版本的 schema 信息,这些信息会被 Mounter 用来解析行变更信息。
  • BarrierTs:由 Owner 向 Processor 发送的控制信息,它会让 Processor 把同步进度阻塞到 BarrierTs 所指定的值。TiCDC 内部有几种不同类型的 BarrierTs,为了简化叙述,本文中提到的 BarrierTs 仅表示 DDL 事件产生的 DDLBarrierTs。
  • OwnerDDLPuller:由 Owner 持有,负责拉取和过滤上游 TiDB 集群的 DDL 事件,并把它们缓存在一个队列中,等待 Owner 处理;此外,它还会维护一个 ResolvedTs,该值为上游 TiKV 发送过来的最新的 ResolvedTs,在没有 DDL 事件到来的时候,Owner 将会使用它来推进 DDLBirrierTs。
  • ProcessorDDLPuller:由 Processor 持有,负责拉取和过滤上游 TiDB 集群的 DDL 事件,然后把它们发送给 Processor 去更新 ProcessorSchemaStorage。
  • DDLSink:由 Owner 持有,负责执行 DDL 到下游。


TiCDC与ETCD

我们还需要知道,TiCDC 集群的元数据都会被存储到 PD 内置的 Etcd 中并定期更新。当一个 TiCDC 集群被部署起来时,每个 Capture 都会向 Etcd 注册自己的信息,这样 Capture 就能够发现彼此的存在,从而完成 Owner 的选举。

竞选到 Owner 角色的 Capture 会作为集群的管理者,也负责监听和响应来自用户的请求。

这里有一个风险点,因为 etcd 的多版本并发控制 (MVCC) 以及 PD 默认的 compaction 间隔是 1 小时,TiCDC 占用的 PD 存储空间与 1 小时内元数据的版本数量成正比,在 v4.0.5、v4.0.6、v4.0.7 三个版本中 TiCDC 存在元数据写入频繁的问题,如果 1 小时内有 1000 张表创建或调度,就会用尽 etcd 的存储空间,导致集群不可用。

特别说明:etcd 存储空间耗尽会出现 etcdserver: mvcc: database space exceeded 错误,需及时清理 etcd 存储空间,否则集群不可用。参考 etcd maintenance space-quota。如果TiCDC 版本为 v4.0.5、v4.0.6 或 v4.0.7,会有比较大的使用风险,强烈建议升级到 v4.0.9 及以后版本。



同步状态

Changefeed 是 TiCDC 中的单个同步任务,负责将一个表或者多个表的变更数据输出到一个指定的下游。TiCDC 集群可以运行和管理多个 Changefeed。

在 TiCDC 运行过程中,同步任务可能会运行出错、手动暂停、恢复,或达到指定的 TargetTs,这些行为都可以导致同步任务状态发生变化。同步任务的状态有:

  • Normal:同步任务正常进行,checkpoint-ts 正常推进。
  • Stopped:同步任务停止,由于用户手动暂停 (pause) 任务。
  • 处于这个状态的 changefeed 会阻挡 GC 推进。
  • Warning:同步任务报错,由于某些可恢复的错误导致同步无法继续进行。
  • 处于这个状态的 changefeed 会阻挡集群 GC 推进。
  • 此时同步任务会不断尝试继续推进,直到状态转为 Normal。超过最大重试时间 30 分钟,changefeed 会进入 failed 状态。
  • Finished:同步任务完成,同步任务进度已经达到预设的目标时间戳 TargetTs。
  • Failed:同步任务失败。
  • 由于发生了某些不可恢复的错误,导致同步无法继续进行,并且无法自动恢复。
  • 为了让用户有足够的时间处理故障,处于这个状态的 changefeed 会阻塞 GC 推进,阻塞时长为 gc-ttl 所设置的值,默认 24 小时。
  • 如果 changefeed 遭遇错误码为 ErrGCTTLExceeded, ErrSnapshotLostByGC 或者 ErrStartTsBeforeGC 类型的错误,任务直接失败,不阻塞集群 GC 推进。

TiCDC核心原理解析_并发处理_03

以上状态流转图中的编号说明如下:

  • ① 执行 pause 暂停同步任务。
  • ② 执行 resume 恢复同步任务。
  • ③ 同步任务运行过程中发生可恢复的错误,自动重试。
  • ④ 同步任务自动重试成功,checkpoint-ts 已经继续推进。
  • ⑤ 同步任务自动重试超过 30 分钟,重试失败,进入 failed 状态。此时 changefeed 会继续阻塞上游 GC,阻塞时长为 gc-ttl 所配置的时长。
  • ⑥ 同步任务遇到不可重试错误,直接进入 failed 状态。此时 changefeed 会继续阻塞上游 GC,阻塞时长为 gc-ttl 所配置的时长。
  • ⑦ 同步任务的同步进度到达 target-ts 设置的值,完成同步。
  • ⑧ 同步任务停滞时间超过 gc-ttl 所指定的时长,因集群会继续推进 GC 而让任务直接失败。


Table Pipeline

每个同步任务,负责同步一张或者多张表,TiCDC 的同步对于单表来说是单线程的,对于多表之间的同步是并行的。对于每个表的处理过程,会放在一个 Table Pipeline 流程内执行完成。TablePipeline 就是一个表数据流动和处理的管道。

TiCDC核心原理解析_存储空间_04

TiCDC 的 Processor 接收到一个同步子任务之后,会为每一张表自动创建出一个 TablePipeline,它主要由 Puller、Sorter、Mounter 和 Sink 构成。各个模块之间是串行的关系,组合在一起完成从上游拉取、排序、加载和同步数据到下游的过程。

TiCDC核心原理解析_存储空间_05

  • Puller: 负责拉取对应表在上游的变更数据,它隐藏了内部大量的实现细节,包括与 TiKV CDC 模块建立 gRPC 连接和反解码数据流等。Puller 从 KV-Client 接收数据并写入到 Sorter 中,并持续推进表级别的 Resovled Ts,标识该表当前接收数据的进度。
  • Sorter: 负责对 Puller 输出的乱序数据进行排序,并且会把 Sink 来不及消费的数据进行落盘,起到一个蓄水池的作用。此时输出的数据是从 TiKV 中扫描出的 key-value,是 bytes 数据。TiCDC 使用 Pebble 作为默认的排序引擎,是基于 LSM 树的 golang 开源实现 。在 TiCDC 中,通过一些手段极大缓解了 LSM 树读写放大的情况。
  • Mounter:根据对应的表的 Schema 信息将行转化为按照表结构组织的数据。Mounter 进行的是一项 CPU 密集型工作,当一个表中所包含的字段较多时,Mounter 会消耗大量的计算资源。
  • Sink:将 Mounter 处理过后的数据进行编解码,转化为 SQL 语句或者 Kafka 消息发送到对应下游。
  • TableSink 作为一种 Table 级别的管理单位,缓存着要下发到 ProcessorSink 的数据,它的主要作用是方便 TiCDC 按照表为单位管理资源和进行调度
  • ProcessorSink 作为真实要与数据库或者 Kafka 建立连接的 Sink 负责 SQL/Kafka 消息的转换和同步


多表同步任务

假设我们创建一个 Changefeed 任务,要同步 test1.tab1test1.tab2test3.tab3test4.tab4 四张表。TiCDC 接收到这个命令之后的处理流程如下:

  1. TiCDC 将这个任务发送给 Owner Capture 进程。
  2. Owner Capture 进程将这个任务的相关定义信息保存在 PD 的 etcd 中。
  3. Owner Capture 将这个任务拆分成若干个 Task,并通知其他 Capture 进程各个 Task 需要完成的任务。
  4. 各个 Capture 进程开始从对应的 TiKV 节点拉取信息,进行处理后完成同步。

TiCDC核心原理解析_数据_06

上图创建了一个同步任务,这个 Changefeed 包含 4 张表,其被拆分成了 3 个任务,以表为单位同步数据为每张表创建一个 Table Pipeline。均匀的分发到了 TiCDC 集群的 3 个 Capture 节点上,在 TiCDC 对这些数据进行了处理之后,数据同步到了下游的系统。



总结

  • TiCDC 内部通过 Puller、Sorter、Mounter 和 Sink 这几个环节串行操作,实现变更数据的拉取、排序、处理和写入下游。
  • 对于单表来说,是一个独立的 Pipeline 处理,可以简单理解为内部是单并发处理;对于多表,是多并发处理。
  • 单个表的同步任务是单并发处理,多个表的同步是多并发处理。
  • TiCDC 会在 PD 注册自己的 GC Safe Point,最多可以阻塞集群 24 小时 GC不推进,即延迟最大是一天。超过一条不处理,PD 会强制推进 GC ,此时 TiCDC 的同步任务会立即失败。
  • 所以,对于 TiCDC 同步的延迟情况,尽量早介入处理,否则会导致超时而出现任务失败的现象。
  • TiCDC 内部会有 Owner 角色进行统一的调度管理,类似 TiKV 的 Leader 角色,保证任务处理的高可用。

标签:Capture,同步,任务,集群,TiCDC,Owner,原理,解析
From: https://blog.51cto.com/tidb/8873023

相关文章

  • 10倍提升-TiCDC性能调优实践
    作者:Jellybean结论先行针对v5.3.0版本的TiCDC,优化Sorter算子内存参数和Sink同步并发可以极大改善同步的性能,测试验证实时同步的QPS从5k优化到60k,提升12倍以上。测试验证,在满负载追数据同步场景,TiCDC的相关参数per-table-memory-quota设为800MB和同步任务......
  • 前端歌谣-第贰拾玖课-构造函数和实例化原理
    前言我是歌谣最好的种树是十年前其次是现在今天继续给大家带来的是构造函数和实例化原理的讲解环境配置npminit-yyarnaddvite-D修改page.json配置端口{"name":"demo1","version":"1.0.0","description":"","main":"index.js&qu......
  • 【独家解析】腾讯产品面试题:为什么顺风车是一口价,快车、专车却不是?
    大家好,这里是小米!今天我要和大家聊一个有趣的话题——腾讯产品面试题中的一个经典问题:“为什么顺风车是一口价,而快车、专车却不是?”这可是个考察逻辑思维和商业洞察力的好问题哦!首先,我们来看一下这个问题的背后,是不是有一些微妙的商业逻辑呢?市场定位与需求分析首先,我们知道,滴滴打车......
  • 在 Windows 11 中为 WSL2 启用 Systemd 以及修复ping不通和DNS无法解析等的问题
    前言今天使用WSL2(Ubuntu22.04.1LTS)的时候,遇到了ping不通的问题,提示:ping:connect:Networkisunreachable以及执行sudoaptupdate命令出现错误:Failedtofetchhttp://archive.ubuntu.com/ubuntu/dists/focal/InReleaseTemporaryfailureresolving'archive.ubunt......
  • 链表面试题解析
    链表面试题解析1.删除链表中=val的所有节点/***Definitionforsingly-linkedlist.*publicclassListNode{*intval;*ListNodenext;*ListNode(){}*ListNode(intval){this.val=val;}*ListNode(intval,ListNodenext){......
  • 05.capability 配置参数解析
    capability配置参数解析Capability简介功能:配置Appium会话,告诉Appium服务器需要自动化的平台的应用程序形式:键值对的集合,键对应设置的名称,值对应设置的值主要分为三部分公共部分ios部分android部分SessionAppium的客户端和服务端之间进行......
  • Applescript成功实现imessage数据筛选,imessage蓝号检测,无痕检测手机号是否注册imess
    一、imessages数据检测的两种方式:1.人工筛选,将要验证的号码输出到文件中,以逗号分隔。再将文件中的号码粘贴到iMessage客户端的地址栏,iMessage客户端会自动逐个检验该号码是否为iMessage账号,检验速度视网速而定。红色表示不是iMessage账号,蓝色表示iMessage账号。2.编写苹果MacOs......
  • 深度解析Python上下文管理器:优雅资源管理与异常处理
    Python是一种功能强大且灵活的编程语言,它提供了许多高级工具和特性来简化开发过程。其中之一就是上下文管理器,它允许开发者更优雅地处理资源管理和异常处理。本文将深入探讨Python中上下文管理器的工作原理、使用方法以及实际应用。1. 什么是上下文管理器?上下文管理器是一种Python......
  • 2022年RHCE认证考题解析最新版—RH294环境【转】
    由于本人10.17已成功考过CSA,经过两周所学的ansible并结合题库整理出来的CE解析版我也是11月月底就要考了,不过这套解析也是可以满足今年的redhat8题库文中可能涉及一些命令的参数解释,如有不懂的伙伴可参考我的笔记Ansibleps:一切模板似的题库考试,都需要经过大脑的理解方可顺利上......
  • Java之可变参数和Collections的详细解析
     1.可变参数在JDK1.5之后,如果我们定义一个方法需要接受多个参数,并且多个参数类型一致,我们可以对其简化.格式:修饰符返回值类型方法名(参数类型...形参名){}底层:其实就是一个数组好处:在传递数据的时候,省的我们自己创建数组并添加元素了,JDK底层帮我们自动创建数组并添加元素了......