diff --git a/TOC.md b/TOC.md index d67cc37e52e8..890195e6fd32 100644 --- a/TOC.md +++ b/TOC.md @@ -187,7 +187,9 @@ - [与 Confluent Cloud 和 Snowflake 进行数据集成](/ticdc/integrate-confluent-using-ticdc.md) - [与 Apache Kafka 和 Apache Flink 进行数据集成](/replicate-data-to-kafka.md) - 参考指南 - - [TiCDC 架构设计与原理](/ticdc/ticdc-architecture.md) + - TiCDC 架构设计与原理 + - [TiCDC 新架构](/ticdc/ticdc-architecture.md) + - [TiCDC 老架构](/ticdc/ticdc-classic-architecture.md) - [TiCDC 数据同步能力详解](/ticdc/ticdc-data-replication-capabilities.md) - [TiCDC Server 配置参数](/ticdc/ticdc-server-config.md) - [TiCDC Changefeed 配置参数](/ticdc/ticdc-changefeed-config.md) diff --git a/br/backup-and-restore-overview.md b/br/backup-and-restore-overview.md index 123a66b584ec..967827f31342 100644 --- a/br/backup-and-restore-overview.md +++ b/br/backup-and-restore-overview.md @@ -119,7 +119,7 @@ TiDB 支持将数据备份到 Amazon S3、Google Cloud Storage (GCS)、Azure Blo | New collation | [#352](https://github.com/pingcap/br/issues/352) | 确保恢复时集群的 `mysql.tidb` 表中 `new_collation_enabled` 变量值和备份时的一致,否则会导致数据索引不一致和 checksum 通不过。更多信息,请参考 [FAQ - BR 为什么会报 `new_collations_enabled_on_first_bootstrap` 不匹配?](/faq/backup-and-restore-faq.md#恢复时为什么会报-new_collation_enabled-不匹配)。 | | 全局临时表 | | 确保使用 BR v5.3.0 及以上版本进行备份和恢复,否则会导致全局临时表的表定义错误。 | | TiDB Lightning 物理导入模式| |上游数据库使用 TiDB Lightning 物理导入模式导入的数据,无法作为数据日志备份下来。推荐在数据导入后执行一次全量备份,细节参考[上游数据库使用 TiDB Lightning 物理导入模式导入数据的恢复](/faq/backup-and-restore-faq.md#上游数据库使用-tidb-lightning-物理导入模式导入数据时为什么无法使用日志备份功能)。| -| TiCDC | | BR v8.2.0 及以上版本:如果在恢复的目标集群有 [CheckpointTS](/ticdc/ticdc-architecture.md#checkpointts) 早于 BackupTS 的 Changefeed,BR 会拒绝执行恢复。BR v8.2.0 之前的版本:如果在恢复的目标集群有任何活跃的 TiCDC Changefeed,BR 会拒绝执行恢复。 | +| TiCDC | | BR v8.2.0 及以上版本:如果在恢复的目标集群有 [CheckpointTS](/ticdc/ticdc-classic-architecture.md#checkpointts) 早于 BackupTS 的 Changefeed,BR 会拒绝执行恢复。BR v8.2.0 之前的版本:如果在恢复的目标集群有任何活跃的 TiCDC Changefeed,BR 会拒绝执行恢复。 | | 向量搜索 | | 确保使用 BR v8.4.0 及以上版本进行备份与恢复。不支持将带有[向量数据类型](/vector-search/vector-search-data-types.md)的表恢复至 v8.4.0 之前的 TiDB 集群。 | ### 版本间兼容性 diff --git a/media/ticdc/ticdc-new-arch-1.png b/media/ticdc/ticdc-new-arch-1.png new file mode 100644 index 000000000000..06b55db0c1eb Binary files /dev/null and b/media/ticdc/ticdc-new-arch-1.png differ diff --git a/media/ticdc/ticdc-new-arch-2.png b/media/ticdc/ticdc-new-arch-2.png new file mode 100644 index 000000000000..16fd0f343fd2 Binary files /dev/null and b/media/ticdc/ticdc-new-arch-2.png differ diff --git a/media/ticdc/ticdc-new-arch-import-grafana.png b/media/ticdc/ticdc-new-arch-import-grafana.png new file mode 100644 index 000000000000..694bfac3c8c3 Binary files /dev/null and b/media/ticdc/ticdc-new-arch-import-grafana.png differ diff --git a/media/ticdc/ticdc-new-arch-metric-event-store.png b/media/ticdc/ticdc-new-arch-metric-event-store.png new file mode 100644 index 000000000000..61fb59cbfcdc Binary files /dev/null and b/media/ticdc/ticdc-new-arch-metric-event-store.png differ diff --git a/media/ticdc/ticdc-new-arch-metric-log-puller.png b/media/ticdc/ticdc-new-arch-metric-log-puller.png new file mode 100644 index 000000000000..4f8e343ede8e Binary files /dev/null and b/media/ticdc/ticdc-new-arch-metric-log-puller.png differ diff --git a/media/ticdc/ticdc-new-arch-metric-server.png b/media/ticdc/ticdc-new-arch-metric-server.png new file mode 100644 index 000000000000..87fcae2fd984 Binary files /dev/null and b/media/ticdc/ticdc-new-arch-metric-server.png differ diff --git a/media/ticdc/ticdc-new-arch-metric-sink.png b/media/ticdc/ticdc-new-arch-metric-sink.png new file mode 100644 index 000000000000..8baf832c4b9f Binary files /dev/null and b/media/ticdc/ticdc-new-arch-metric-sink.png differ diff --git a/media/ticdc/ticdc-new-arch-metric-summary.png b/media/ticdc/ticdc-new-arch-metric-summary.png new file mode 100644 index 000000000000..c3f7d1d1a351 Binary files /dev/null and b/media/ticdc/ticdc-new-arch-metric-summary.png differ diff --git a/releases/release-8.2.0.md b/releases/release-8.2.0.md index 03002adf5c24..7e3e717a250d 100644 --- a/releases/release-8.2.0.md +++ b/releases/release-8.2.0.md @@ -163,7 +163,7 @@ TiDB 版本:8.2.0 * 使用 [`IMPORT INTO`](/sql-statements/sql-statement-import-into.md) 导入 CSV 文件时,如果指定 `SPLIT_FILE` 参数将一个大 CSV 文件切分为多个小 CSV 文件来提升并发和导入性能,需显式指定行结束符 `LINES_TERMINATED_BY`,参数的取值为 `\r`、`\n` 或 `\r\n`。如果没有指定行结束符,可能导致 CSV 文件数据解析异常。[#37338](https://github.com/pingcap/tidb/issues/37338) @[lance6716](https://github.com/lance6716) -* 在 BR v8.2.0 之前的版本中,当集群存在 TiCDC 同步任务时,BR 不支持进行[数据恢复](/br/backup-and-restore-overview.md)。从 BR 8.2.0 起,BR 数据恢复对 TiCDC 的限制被放宽:如果所恢复数据的 BackupTS(即备份时间)早于 Changefeed 的 [CheckpointTS](/ticdc/ticdc-architecture.md#checkpointts)(即记录当前同步进度的时间戳),BR 数据恢复可以正常进行。考虑到 BackupTS 的时间通常较早,此时可以认为绝大部分场景下,当集群存在 TiCDC 同步任务时,BR 都可以进行数据恢复。[#53131](https://github.com/pingcap/tidb/issues/53131) @[YuJuncen](https://github.com/YuJuncen) +* 在 BR v8.2.0 之前的版本中,当集群存在 TiCDC 同步任务时,BR 不支持进行[数据恢复](/br/backup-and-restore-overview.md)。从 BR 8.2.0 起,BR 数据恢复对 TiCDC 的限制被放宽:如果所恢复数据的 BackupTS(即备份时间)早于 Changefeed 的 [CheckpointTS](/ticdc/ticdc-classic-architecture.md#checkpointts)(即记录当前同步进度的时间戳),BR 数据恢复可以正常进行。考虑到 BackupTS 的时间通常较早,此时可以认为绝大部分场景下,当集群存在 TiCDC 同步任务时,BR 都可以进行数据恢复。[#53131](https://github.com/pingcap/tidb/issues/53131) @[YuJuncen](https://github.com/YuJuncen) ### MySQL 兼容性 @@ -261,7 +261,7 @@ TiDB 版本:8.2.0 + Backup & Restore (BR) - 优化备份功能,提升在大量表备份过程中遇到节点重启、扩容或网络抖动时的备份性能和稳定性 [#52534](https://github.com/pingcap/tidb/issues/52534) @[3pointer](https://github.com/3pointer) - - 优化恢复过程中对 TiCDC Changefeed 的细粒度检查,如果 Changefeed 的 [CheckpointTS](/ticdc/ticdc-architecture.md#checkpointts) 晚于数据的备份时间,则不会影响恢复操作,从而减少不必要的等待时间,提升用户体验 [#53131](https://github.com/pingcap/tidb/issues/53131) @[YuJuncen](https://github.com/YuJuncen) + - 优化恢复过程中对 TiCDC Changefeed 的细粒度检查,如果 Changefeed 的 [CheckpointTS](/ticdc/ticdc-classic-architecture.md#checkpointts) 晚于数据的备份时间,则不会影响恢复操作,从而减少不必要的等待时间,提升用户体验 [#53131](https://github.com/pingcap/tidb/issues/53131) @[YuJuncen](https://github.com/YuJuncen) - 为 [`BACKUP`](/sql-statements/sql-statement-backup.md) 语句和 [`RESTORE`](/sql-statements/sql-statement-restore.md) 语句添加了多个常用参数选项,例如 `CHECKSUM_CONCURRENCY` [#53040](https://github.com/pingcap/tidb/issues/53040) @[RidRisR](https://github.com/RidRisR) - 去掉除了 `br log restore` 子命令之外其它 `br log` 子命令对 TiDB `domain` 数据结构的载入,降低内存消耗 [#52088](https://github.com/pingcap/tidb/issues/52088) @[Leavrth](https://github.com/Leavrth) - 支持对日志备份过程中生成的临时文件进行加密 [#15083](https://github.com/tikv/tikv/issues/15083) @[YuJuncen](https://github.com/YuJuncen) diff --git a/ticdc/monitor-ticdc.md b/ticdc/monitor-ticdc.md index 503a89e2eba7..30f7c802fbd0 100644 --- a/ticdc/monitor-ticdc.md +++ b/ticdc/monitor-ticdc.md @@ -6,7 +6,7 @@ aliases: ['/zh/tidb/dev/ticdc-grafana-dashboard'] # TiCDC 详细监控指标 -使用 TiUP 部署 TiDB 集群时,一键部署的监控系统面板包含 TiCDC 面板。本文档对 TiCDC 监控面板上的各项指标进行详细说明。在日常运维中,运维人员可通过观察 TiCDC 面板上的指标了解 TiCDC 当前的状态。 +本文档对 TiCDC 监控面板上的各项指标进行详细说明。在日常运维中,运维人员可通过观察 TiCDC 面板上的指标了解 TiCDC 当前的状态。 本文档的对指标的介绍基于以下同步任务,即使用默认配置同步数据到 MySQL。 @@ -14,18 +14,126 @@ aliases: ['/zh/tidb/dev/ticdc-grafana-dashboard'] cdc cli changefeed create --server=http://10.0.10.25:8300 --sink-uri="mysql://root:123456@127.0.0.1:3306/" --changefeed-id="simple-replication-task" ``` -下图显示了 TiCDC Dashboard 各监控面板: +## TiCDC 新架构监控指标 -![TiCDC Dashboard - Overview](/media/ticdc/ticdc-dashboard-overview.png) +[TiCDC 新架构](/ticdc/ticdc-architecture.md)的监控面板 **TiCDC-New-Arch** 暂时未集成到 TiUP 中。要在 Grafana 中查看相关监控信息,你需要手动导入 TiCDC 监控指标文件: -各监控面板说明如下: +1. 下载 TiCDC 新架构监控指标文件 + + ```shell + wget https://raw.githubusercontent.com/pingcap/ticdc/refs/heads/release-8.5/metrics/grafana/ticdc_new_arch.json + ``` + +2. 在 Grafana 页面导入下载的监控指标文件 + + ![导入监控指标文件](/media/ticdc/ticdc-new-arch-import-grafana.png) + +TiCDC 新架构的监控面板主要包括以下部分: + +- [**Summary**](#summary-面板):TiCDC 集群的概要信息 +- [**Server**](#server-面板):TiDB 集群中 TiKV 节点和 TiCDC 节点的概要信息 +- [**Log Puller**](#log-puller-面板):TiCDC Log Puller 模块的详细信息 +- [**Event Store**](#event-store-面板):TiCDC Event Store 模块的详细信息 +- [**Sink**](#sink-面板):TiCDC Sink 模块的详细信息 + +### Summary 面板 + +**Summary** 面板示例如下: + +![Summary](/media/ticdc/ticdc-new-arch-metric-summary.png) + +**Summary** 面板的各指标说明如下: + +- Changefeed Checkpoint Lag:同步任务在下游与上游之间的时序差距 +- Changefeed ResolvedTs Lag:TiCDC 节点内部处理进度与上游数据库的时序差距 +- Upstream Write Bytes/s:上游数据库的写入吞吐量 +- TiCDC Input Bytes/s:TiCDC 每秒从上游接收的数据量 +- Sink Event Row Count/s:TiCDC 每秒向下游写入的数据行数 +- Sink Write Bytes/s:TiCDC 每秒向下游写入的数据量 +- The Status of Changefeeds:各 Changefeed 的状态 +- Table Dispatcher Count:各 Changefeed 对应的 Dispatcher 数量 +- Memory Quota:Event Collector 内存配额及使用量,使用量过大时会导致限流 + +### Server 面板 + +**Server** 面板示例如下: + +![Server](/media/ticdc/ticdc-new-arch-metric-server.png) + +**Server** 面板的各指标说明如下: + +- Uptime:TiKV 节点和 TiCDC 节点已经运行的时间 +- Goroutine Count:TiCDC 节点 Goroutine 的个数 +- Open FD Count:TiCDC 节点打开的文件句柄个数 +- CPU Usage:TiCDC 节点使用的 CPU +- Memory Usage:TiCDC 节点使用的内存 +- Ownership History:TiCDC 集群中 Owner 节点的历史记录 +- PD Leader History:上游 TiDB 集群中 PD Leader 节点的历史记录 + +### Log Puller 面板 + +**Log Puller** 面板示例如下: + +![Log Puller](/media/ticdc/ticdc-new-arch-metric-log-puller.png) + +**Log Puller** 面板的各指标说明如下: + +- Input Events/s:TiCDC 每秒收到的事件数 +- Unresolved Region Request Count:TiCDC 已经发送但尚未完成的 Region 增量扫描请求数 +- Region Request Finish Scan Duration:Region 增量扫描的耗时 +- Subscribed Region Count:订阅的 Region 总数 +- Memory Quota:Log Puller 内存配额及使用量,使用量过大会导致限流 +- Resolved Ts Batch Size (Regions):单个 Resolved Ts 事件包含的 Region 数量 + +### Event Store 面板 + +**Event Store** 面板示例如下: + +![Event Store](/media/ticdc/ticdc-new-arch-metric-event-store.png) + +**Event Store** 面板的各指标说明如下: + +- Resolved Ts Lag:Event Store 处理进度与上游数据库的时序差距 +- Register Dispatcher StartTs Lag:Dispatcher 注册请求的 StartTs 与当前时间点之间的时序差距 +- Subscriptions Resolved Ts Lag:Subscription 处理进度与上游数据库的时序差距 +- Subscriptions Data GC Lag:Subscription 数据 GC 进度与当前时间点的时序差距 +- Input Event Count/s:Event Store 每秒处理的事件数 +- Input Bytes/s:Event Store 每秒处理的数据量 +- Write Requests/s:Event Store 每秒执行的写入请求数量 +- Write Worker Busy Ratio:Event Store 写线程的 I/O 时间占总运行时间的比例 +- Compressed Rows/s:Event Store 每秒压缩的数据行数(仅当行大小超过设定阈值时触发压缩) +- Write Duration:Event Store 写入操作的耗时 +- Write Batch Size:单次写入操作的批量数据大小 +- Write Batch Event Count:单次写入批次中包含的行变更数 +- Data Size On Disk:Event Store 在磁盘上占用的数据总量 +- Data Size In Memory:Event Store 在内存中占用的数据总量 +- Scan Requests/s:Event Store 每秒执行的扫描请求数量 +- Scan Bytes/s:Event Store 每秒扫描的数据量 + +### Sink 面板 + +**Sink** 面板示例如下: + +![Sink](/media/ticdc/ticdc-new-arch-metric-sink.png) + +**Sink** 面板的各指标说明如下: + +- Output Row Batch Count:Sink 每批次写入 DML 的平均行数。 +- Output Row Count (per second):每秒向下游写入的 DML 行数 +- Output DDL Executing Duration:当前节点上对应 Changefeed 执行 DDL Event 的耗时 +- Sink Error Count / m:Sink 模块每分钟的报错信息数量 +- Output DDL Count / Minutes:当前节点上对应 Changefeed 每分钟执行的 DDL 数量 + +## TiCDC 老架构监控指标 + +使用 TiUP 部署 TiDB 集群时,一键部署的监控系统面板包含 [TiCDC 老架构](/ticdc/ticdc-classic-architecture.md)监控面板。TiCDC 老架构主要监控面板说明如下: - [**Server**](#server-面板):TiDB 集群中 TiKV 节点和 TiCDC 节点的概要信息 - [**Changefeed**](#changefeed-面板):TiCDC 同步任务的详细信息 - [**Events**](#events-面板):TiCDC 内部数据流转的详细信息 - [**TiKV**](#tikv-面板):TiKV 中和 TiCDC 相关的详细信息 -## Server 面板 +### Server 面板 **Server** 面板示例如下: @@ -41,7 +149,7 @@ cdc cli changefeed create --server=http://10.0.10.25:8300 --sink-uri="mysql://ro - CPU usage:TiCDC 节点使用的 CPU - Memory usage:TiCDC 节点使用的内存 -## Changefeed 面板 +### Changefeed 面板 **Changefeed** 面板示例如下: @@ -73,7 +181,7 @@ cdc cli changefeed create --server=http://10.0.10.25:8300 --sink-uri="mysql://ro - Changefeed catch-up ETA:同步完上游写入的数据所需时间的估计值。当上游的写入速度大于 TiCDC 同步速度时,该值可能会异常的大。(由于 TiCDC 的同步速度受到较多因素制约,因此该值仅供参考,不能完全代表实际所需的同步时间。) -## Events 面板 +### Events 面板 **Events** 面板示例如下: @@ -103,7 +211,7 @@ cdc cli changefeed create --server=http://10.0.10.25:8300 --sink-uri="mysql://ro - KV client dispatch events/s:TiCDC 节点内部 KV client 模块每秒分发数据变更的个数 - KV client batch resolved size:TiKV 批量发给 TiCDC 的 resolved ts 消息的大小 -## TiKV 面板 +### TiKV 面板 **TiKV** 面板示例如下: diff --git a/ticdc/ticdc-architecture.md b/ticdc/ticdc-architecture.md index bcc7086f0766..a2a0d1e818ec 100644 --- a/ticdc/ticdc-architecture.md +++ b/ticdc/ticdc-architecture.md @@ -1,175 +1,244 @@ --- -title: TiCDC 架构设计与原理 -summary: 了解 TiCDC 软件的架构设计和运行原理。 +title: TiCDC 新架构 +summary: 介绍 TiCDC 新架构的主要特性、架构设计、升级部署指南以及其他注意事项。 --- -# TiCDC 架构设计与原理 +# TiCDC 新架构 -## TiCDC 软件架构 +从 [TiCDC v8.5.4-release.1](https://github.com/pingcap/ticdc/releases/tag/v8.5.4-release.1) 版本起,TiCDC 引入新架构,显著提升了实时数据复制的性能、可扩展性与稳定性,同时降低了资源成本。新架构重新设计了 TiCDC 的核心组件并优化了数据处理流程,具有以下优势: -TiCDC 集群由多个 TiCDC 对等节点组成,是一种分布式无状态的架构设计。TiCDC 集群及节点内部组件的设计如下图所示: +- **更高的单节点性能**:单节点可支持最多 50 万张表的同步任务,宽表场景下单节点同步流量最高可达 190 MiB/s。 +- **更强的扩展能力**:集群同步能力接近线性扩展,单集群可扩展至超过 100 个节点,支持超 1 万个 Changefeed;单个 Changefeed 可支持百万级表的同步任务。 +- **更高的稳定性**:在高流量、频繁 DDL 操作及集群扩缩容等场景下,Changefeed 的延迟更低且更加稳定。通过资源隔离和优先级调度,减少了多个 Changefeed 任务之间的相互干扰。 +- **更低的资源成本**:通过改进资源利用率,减少冗余开销。在典型场景下,CPU 和内存等资源的使用量降低高达 50%。 -![TiCDC architecture](/media/ticdc/ticdc-architecture-1.jpg) +## 架构设计 -## 组件介绍 +![TiCDC 新架构](/media/ticdc/ticdc-new-arch-1.png) -上图中,TiCDC 集群由多个运行了 TiCDC 实例的节点组成,每个 TiCDC 实例都运行一个 Capture 进程。多个 Capture 进程中会有一个被选举成为 Owner Capture,负责完成 TiCDC 集群的负载调度、DDL 语句同步和其它管理任务。 +TiCDC 新架构由 Log Service 和 Downstream Adapter 两大核心组件构成。 -每个 Capture 进程包含一个或多个 Processor 线程,用于同步上游 TiDB 集群中的表数据。由于 TiCDC 同步数据的最小单位是表,所以 Processor 是由多条 table pipeline 构成的。 +- Log Service:作为核心数据服务层,Log Service 负责实时拉取上游 TiDB 集群的行变更和 DDL 变更等信息,并将变更数据临时存储在本地磁盘上。此外,它还负责响应 Downstream Adapter 的数据请求,定时将 DML 和 DDL 数据合并排序并推送至 Downstream Adapter。 +- Downstream Adapter:作为下游数据同步适配层,Downstream Adapter 负责处理用户发起的 Changefeed 运维操作,调度生成相关同步任务,从 Log Service 获取数据并同步至下游系统。 -每条 pipeline 包含 Puller、Sorter、Mounter 和 Sink 模块,如下图。 +TiCDC 新架构通过将整体架构拆分成有状态和无状态的两部分,显著提升了系统的可扩展性、可靠性和灵活性。Log Service 作为有状态组件,专注于数据的获取、排序和存储,通过与 Changefeed 业务逻辑的解耦,实现了数据在多个 Changefeed 间的共享,有效提高了资源利用率,降低了系统开销。Downstream Adapter 作为无状态组件,采用轻量级调度机制,支持任务在不同实例间的快速迁移,并根据负载变化灵活调整同步任务的拆分与合并,确保在各种场景下都能实现低延迟的数据同步。 -![TiCDC architecture](/media/ticdc/ticdc-architecture-2.jpg) +## 新老架构对比 -各个模块之间是串行的关系,组合在一起完成从上游拉取、排序、加载和同步数据到下游的过程,其中: +新架构旨在解决系统规模持续扩展过程中常见的性能瓶颈、稳定性不足及扩展性受限等核心问题。相较于[老架构](/ticdc/ticdc-classic-architecture.md),新架构在以下关键维度实现了显著优化: -- Puller:从 TiKV 节点获取 DDL 和行变更信息。 -- Sorter:将接收到的变更在 TiCDC 内按照时间戳进行升序排序。 -- Mounter:将变更按照对应的 Schema 信息转换成 TiCDC 可以处理的格式。 -- Sink:将对应的变更应用到下游系统。 +| 特性 | TiCDC 老架构 | TiCDC 新架构 | +| ------------------------ | ---------------------------------------- | ---------------------------------------- | +| **处理逻辑驱动方式** | Timer Driven(定时器驱动) | Event Driven(事件驱动) | +| **任务触发机制** | 定时器触发的大循环,每隔 50 ms 检查任务,处理性能有限 | 由事件驱动,包括 DML、DDL 变更及 Changefeed 操作,队列中的事件会被尽快处理,无需等待 50 ms 的固定间隔,从而减少了额外的延迟 | +| **任务调度方式** | 每个 Changefeed 运行一个主循环,轮询检查任务 | 事件被放入队列后,由多个线程并发消费处理 | +| **任务处理效率** | 每个任务需要经过多个周期,存在性能瓶颈 | 事件可以立即处理,无需等待固定间隔,减少延迟 | +| **资源消耗** | 频繁检查不活跃表,浪费 CPU 资源 | 消费线程仅处理队列中的事件,无需检查不活跃任务 | +| **复杂度** | O(n),表数量增多时性能下降 | O(1),不受表数量影响,效率更高 | +| **CPU 利用率** | 每个 Changefeed 只能利用一个逻辑 CPU | 能充分利用多核 CPU 的并行处理能力 | +| **扩展能力** | 受限于 CPU 数量,扩展性差 | 通过多线程消费和事件队列,可扩展性强 | +| **Changefeed 干扰问题** | 中央控制节点 (Owner) 会造成 Changefeed 之间的干扰 | 事件驱动模式避免了 Changefeed 之间的干扰 | -为了实现高可用,每个 TiCDC 集群都包含多个 TiCDC 节点,这些节点定期向 PD 集群中的 etcd 集群汇报自己的状态,并选举出其中一个节点作为 TiCDC 集群的 Owner。Owner 采用 etcd 统一存储状态来进行调度,并将调度结果直接写入 etcd。Processor 按照状态完成对应的任务,如果 Processor 所在节点出现异常,集群会将表调度到其他节点。如果 Owner 节点出现异常,其他节点的 Capture 进程会选举出新的 Owner,如下图所示: +![TiCDC 新老架构对比](/media/ticdc/ticdc-new-arch-2.png) -![TiCDC architecture](/media/ticdc/ticdc-architecture-3.PNG) +## 新老架构选择 -## Changefeed 和 Task +如果你的业务满足以下任一条件,建议从 [TiCDC 老架构](/ticdc/ticdc-classic-architecture.md)切换至TiCDC 新架构,以获得更优的性能与稳定性: -TiCDC 中的 Changefeed 和 Task 是两个逻辑概念,前者是分配同步任务的方式,后者是同步任务拆分后的子任务名称,具体描述如下: +- 增量扫描存在性能瓶颈:增量扫描任务长时间无法完成,导致同步延迟持续上升。 +- 超高流量场景:Changefeed 总体流量超过 700 MiB/s。 +- MySQL Sink 中存在超高流量写入的单表:目标表结构满足**有且仅有**一个主键或非空唯一键。 +- 海量表同步场景:同步的表数量超过 10 万张。 +- 高频 DDL 操作引发延迟:频繁执行 DDL 语句导致同步延迟显著上升。 -- Changefeed:代表一个同步任务,携带了需要同步的表信息,以及对应的下游信息和一些其他的配置信息。 +## 新功能介绍 -- Task:当 TiCDC 接收到对应的同步任务之后,就会把这个任务拆分为若干个称之为 Task 的子任务,分配给 TiCDC 集群的各个节点上的 Capture 进程进行处理。 +新架构支持为 MySQL Sink 启用**表级任务拆分**。你可以通过在 Changefeed 配置中设置 `scheduler.enable-table-across-nodes = true` 来启用该功能。 -例如: +启用后,当**有且仅有一个主键或非空唯一键**的表满足以下任一条件时,TiCDC 会自动将其拆分并分发到多个节点并行执行同步,从而提升同步效率与资源利用率: -``` -cdc cli changefeed create --server="http://127.0.0.1:8300" --sink-uri="kafka://127.0.0.1:9092/cdc-test?kafka-version=2.4.0&partition-num=6&max-message-bytes=67108864&replication-factor=1" -cat changefeed.toml -...... -[sink] -dispatchers = [ - {matcher = ['test1.tab1', 'test2.tab2'], topic = "{schema}_{table}"}, - {matcher = ['test3.tab3', 'test4.tab4'], topic = "{schema}_{table}"}, -] -``` +- 表的 Region 数超过配置的阈值(默认 `100000`,可通过 `scheduler.region-threshold` 调整)。 +- 表的写入流量超过配置的阈值(默认未开启,可通过 `scheduler.write-key-threshold` 设置)。 + +## 兼容性说明 + +### DDL 进度表 -关于命令中参数的详细释义,参考 [TiCDC Changefeed 配置参数](/ticdc/ticdc-changefeed-config.md)。 +在 TiCDC 的老架构中,DDL 的同步是完全串行进行的,因此同步进度仅需通过 Changefeed 的 CheckpointTs 来标识。然而,在新架构中,为了提高 DDL 同步效率,TiCDC 会尽可能并行同步不同表的 DDL 变更。为了在下游 MySQL 兼容数据库中准确记录各表的 DDL 同步进度,TiCDC 新架构会在下游数据库中创建一张名为 `tidb_cdc.ddl_ts_v1` 的表,专门用于存储 Changefeed 的 DDL 同步进度信息。 -以上命令创建了一个到 Kafka 集群的 Changefeed 任务,需要同步 `test1.tab1`、`test1.tab2`、`test3.tab3` 和 `test4.tab4` 四张表。TiCDC 接收到这个命令之后的处理流程如下: +### DDL 同步行为变更 -1. TiCDC 将这个任务发送给 Owner Capture 进程。 -2. Owner Capture 进程将这个任务的相关定义信息保存在 PD 的 etcd 中。 -3. Owner Capture 将这个任务拆分成若干个 Task,并通知其他 Capture 进程各个 Task 需要完成的任务。 -4. 各个 Capture 进程开始从对应的 TiKV 节点拉取信息,进行处理后完成同步。 +- TiCDC 老架构不支持同步互换表名的 DDL(例如 `RENAME TABLE a TO c, b TO a, c TO b;`),TiCDC 新架构已支持此类 DDL 的同步。 -如果将 Changefeed 和 Task 也包含到上文中提及的架构图,完整的 TiCDC 架构图如下: +- TiCDC 新架构统一并简化了 Rename DDL 的过滤规则。 -![TiCDC architecture](/media/ticdc/ticdc-architecture-6.jpg) + - 在 TiCDC 老架构中,过滤逻辑如下 -上图创建了一个 Changefeed,需要同步 4 张表,这个 Changefeed 被拆分成了 3 个任务,均匀的分发到了 TiCDC 集群的 3 个 Capture 节点上,在 TiCDC 对这些数据进行了处理之后,数据同步到了下游的系统。 + - 单表 Rename:仅要求旧表名符合过滤规则即可同步。 + - 多表 Rename:必须所有旧表名和新表名均符合过滤规则,才会同步。 -目前 TiCDC 支持的下游系统包含 MySQL、TiDB 和 Kafka。上面的过程只是讲解了 Changefeed 级别数据流转的基本过程,接下来,本文将以处理表 `table1` 的任务 Task1 为例,从更加详细的层面来描述 TiCDC 处理数据的过程: + - 在新架构中,无论单表还是多表 Rename,只要语句中的旧表名符合过滤规则,该 DDL 即会被同步。 -![TiCDC architecture](/media/ticdc/ticdc-architecture-5.jpg) + 以下面的过滤规则为例: -1. 推流:发生数据改变时,TiKV 集群将数据主动推送给 Puller 模块。 -2. 增量扫:Puller 模块在发现收到的数据改变不连续的时候,向 TiKV 节点主动拉取需要的数据。 -3. 排序:Sorter 模块对获取的数据按照时间进行排序,并将排好序的数据发送给 Mounter。 -4. 装载:Mounter 模块收到数据变更后,根据表的 schema 信息,将数据变更装载成 TiCDC sink 可以理解的格式。 -5. 同步:Sink 模块根据下游的类型将数据变更同步到下游。 + ```toml + [filter] + rules = ['test.t*'] + ``` -由于 TiCDC 的上游是支持事务的分布式关系型数据库 TiDB,在同步数据的时候,如何保证数据的一致性,以及在同步多张表的时候,如何保证事务的一致性,都是很大的挑战。下面的章节会介绍 TiCDC 在确保事务特性时所使用的关键技术和概念。 + - 在 TiCDC 老架构中:对于单表 Rename,如 `RENAME TABLE test.t1 TO ignore.t1`,因旧表名 `test.t1` 匹配规则,会被同步。对于多表 Rename,如 `RENAME TABLE test.t1 TO ignore.t1, test.t2 TO test.t22;`,由于新表名 `ignore.t1` 不匹配规则,不会被同步。 + - 在 TiCDC 新架构中:由于 `RENAME TABLE test.t1 TO ignore.t1` 和 `RENAME TABLE test.t1 TO ignore.t1, test.t2 TO test.t22;` 中的旧表名均匹配规则,这两条 DDL 均会被同步。 -## TiCDC 关键概念 +## 使用限制 -当 TiCDC 对应的下游系统是关系型数据库时,TiCDC 在同步数据的时候会确保单表事务的数据一致性,以及多表事务的最终一致性。另外,TiCDC 会确保上游 TiDB 集群发生过的数据变更能够被 TiCDC 向任意下游最少同步一次。 +目前,TiCDC 新架构已完整实现旧架构的全部功能,但其中部分功能尚未经过全面的测试验证。为确保系统稳定性,暂不建议在核心生产环境中使用以下功能: -### 架构相关概念 +- [Syncpoint](/ticdc/ticdc-upstream-downstream-check.md) +- [Redo Log](/ticdc/ticdc-sink-to-mysql.md#灾难场景的最终一致性复制) +- [Pulsar Sink](/ticdc/ticdc-sink-to-pulsar.md) +- [Storage Sink](/ticdc/ticdc-sink-to-cloud-storage.md) -- Capture:TiCDC 节点的运行进程,多个 Capture 进程构成了 TiCDC 集群,Capture 进程负责 TiKV 的数据变更的同步,包括接收和主动拉取两种方式,并向下游同步数据。 -- Capture Owner:是一种 Capture 的角色,每个 TiCDC 集群同一时刻最多只存在一个 Capture Owner 角色,负责集群内部的调度。 -- Processor:是 Capture 内部的逻辑线程,每个 Processor 负责处理同一个同步流中一个或多个 table 的数据。一个 Capture 节点可以运行多个 Processor。 -- ChangeFeed:一个由用户启动的从上游 TiDB 同步到下游的任务,其中包含多个 Task,Task 会分布在不同的 Capture 节点进行数据同步处理。 +此外,TiCDC 新架构目前暂不支持将大事务拆分为多个批次同步至下游,因此在处理超大事务时仍存在 OOM 风险,请在使用前评估相关影响。 -### 时间戳相关概念 +## 升级指南 -由于 TiCDC 需要确保数据被至少一次同步到下游,并且确保一定的一致性,因此引入了一系列时间戳(Timestamp,简称 TS)来对数据同步的状态进行描述。 +TiCDC 新架构仅支持 v7.5.0 或者以上版本的 TiDB 集群,使用之前需要确保 TiDB 集群版本满足该要求。 -#### ResolvedTS +你可以通过 TiUP 或 TiDB Operator 部署 TiCDC 新架构。 -这个时间戳在 TiKV 和 TiCDC 中都存在。 + +
-- TiKV 节点中的 ResolvedTS:代表某一个 Region leader 上开始时间最早的事务的开始时间,即:ResolvedTS = max(ResolvedTS, min(StartTS))。因为每个 TiDB 集群包含多个 TiKV 节点,所有 TiKV 节点上的 Region leader 的 ResolvedTS 的最小值,被称为 Global ResolvedTS。TiDB 集群确保 Global ResolvedTS 之前的事务都被提交了,或者可以认为这个时间戳之前不存在未提交的事务。 +以下为通过 TiUP 部署 TiCDC 新架构的步骤: -- TiCDC 节点中的 ResolvedTS: +1. 如果你的 TiDB 集群中尚无 TiCDC 节点,参考[扩容 TiCDC 节点](/scale-tidb-using-tiup.md#扩容-ticdc-节点)在集群中扩容新的 TiCDC 节点,否则跳过该步骤。 - - table ResolvedTS:每张表都会有的表级别 ResolvedTS,表示这张表已经从 TiKV 接收到的数据改变的最低水位,可以简单的认为和 TiKV 节点上这张表的各个 Region 的 ResolvedTS 的最小值是相同的。 - - global ResolvedTS:各个 TiCDC 节点上的 Processor ResolvedTS 的最小值。由于 TiCDC 每个节点上都会存在一个或多个 Processor,每个 Processor 又对应多个 table pipeline。 +2. 下载 TiCDC 新架构离线包。 - 对于 TiCDC 节点来说,TiKV 节点发送过来的 ResolvedTS 信息是一种特殊的事件,它只包含一个格式为 `` 的特殊事件。通常情况下,ResolvedTS 满足以下约束: + 离线包下载链接格式为 `https://tiup-mirrors.pingcap.com/cdc-${version}-${os}-${arch}.tar.gz`。其中,`${version}` 为 TiCDC 版本号,`${os}` 为你的操作系统,`${arch}` 为组件运行的平台(`amd64` 或 `arm64`)。 + 例如,可以使用以下命令下载 Linux 系统 x86-64 架构的 TiCDC v8.5.4-release.1 的离线包: + + ```shell + wget https://tiup-mirrors.pingcap.com/cdc-v8.5.4-release.1-linux-amd64.tar.gz ``` - table ResolvedTS >= global ResolvedTS + +3. 如果集群中已经有 Changefeed,请参考[停止同步任务](/ticdc/ticdc-manage-changefeed.md#停止同步任务)暂停所有的 Changefeed 同步任务。例如: + + ```shell + # cdc 默认服务端口为 8300 + cdc cli changefeed pause --server=http://:8300 --changefeed-id ``` -#### CheckpointTS +4. 使用 [`tiup cluster patch`](/tiup/tiup-component-cluster-patch.md) 命令将下载的 TiCDC 二进制文件动态替换到你的 TiDB 集群中: -这个时间戳只在 TiCDC 中存在,它表示 TiCDC 已经同步给下游的数据的最低水位线,即 TiCDC 认为在这个时间戳之前的数据已经被同步到下游系统了。由于 TiCDC 同步数据的单位是表,所以 table CheckpointTS 表示表级别的同步数据的水位线,Processor CheckpointTS 表示各个 Processor 中最小的 table CheckpointTS;Global checkpointTS 表示各个 Processor checkpointTS 中最低的 checkpointTS。通常情况下,Checkpoint TS 满足以下约束: + ```shell + tiup cluster patch ./cdc-v8.5.4-release.1-linux-amd64.tar.gz -R cdc + ``` -``` -table CheckpointTS >= global CheckpointTS -``` +5. 通过 [`tiup cluster edit-config`](/tiup/tiup-component-cluster-edit-config.md) 命令更新 TiCDC 配置以启用 TiCDC 新架构: -因为 TiCDC 只会复制小于 global ResolvedTS 的数据到下游,所以存在下面的约束: + ```shell + tiup cluster edit-config + ``` -``` -table ResolvedTS >= global ResolvedTS >= table CheckpointTS >= global CheckpointTS -``` + ```yaml + server_configs: + cdc: + newarch: true + ``` + +6. 参考[恢复同步任务](/ticdc/ticdc-manage-changefeed.md#恢复同步任务)恢复所有的 Changefeed 同步任务。 -随着数据的改变和事务的提交,TiKV 节点上的 ResolvedTS 会不断的向前推进,TiCDC 节点的 Puller 模块也会不断的收到 TiKV 推流过来的数据,并且根据收到的信息决定是否执行增量扫的过程,从而确保数据改变都能够被发送到 TiCDC 节点上。Sorter 模块则负责将 Puller 模块收到的信息按照时间戳进行升序排序,从而确保数据在表级别是满足一致性的。接下来,Mounter 模块把上游的数据改变装配成 Sink 模块可以消费的格式,并发送给 Sink,而 Sink 则负责把 CheckpointTS 到 ResolvedTS 之间的数据改变,按照发生的 TS 顺序同步到下游,并在下游返回后推进 CheckpointTS。 + ```shell + # cdc 默认服务端口为 8300 + cdc cli changefeed resume --server=http://:8300 --changefeed-id + ``` + +
+
+ +以下为通过 TiDB Operator 部署 TiCDC 新架构的步骤: + +- 如果现有 TiDB 集群中没有 TiCDC 组件,参考[在现有 TiDB 集群上新增 TiCDC 组件](https://docs.pingcap.com/zh/tidb-in-kubernetes/stable/deploy-ticdc/#在现有-tidb-集群上新增-ticdc-组件)在集群中扩容新的 TiCDC 节点。操作时,只需在集群配置文件中将 TiCDC 的镜像版本指定为新架构版本即可。 + + 示例如下: + + ```yaml + spec: + ticdc: + baseImage: pingcap/ticdc + version: v8.5.4-release.1 + replicas: 3 + config: + newarch = true + ``` + +- 如果现有 TiDB 集群中已有 TiCDC 组件,请按以下步骤操作: -上面的内容只介绍了和 DML 语句相关的数据改变,并没有包含 DDL 相关的内容。下面对 DDL 语句相关的关键概念进行介绍。 + 1. 如果集群中已经有 Changefeed,暂停所有的 Changefeed 同步任务。 -#### Barrier TS + ```shell + kubectl exec -it ${pod_name} -n ${namespace} -- sh + ``` -当系统发生 DDL 变更或者用户使用了 TiCDC 的 Syncpoint 时会产生的一个时间戳。 + ```shell + # 通过 TiDB Operator 部署的 TiCDC 服务器的默认端口为 8301 + /cdc cli changefeed pause --server=http://127.0.0.1:8301 --changefeed-id + ``` -- DDL:这个时间戳会用来确保在这个 DDL 语句之前的改变都被应用到下游,之后执行对应的 DDL 语句,在 DDL 语句同步完成之后再同步其他的数据改变。由于 DDL 语句的处理是 Owner 角色的 Capture 负责的,DDL 语句对应的 Barrier TS 只会由 Owner 节点产生。 -- Syncpoint:当你启用 TiCDC 的 Syncpoint 特性后,TiCDC 会根据你指定的间隔产生一个 Barrier TS。等所有表都同步到这个 Barrier TS 后,TiCDC 将此刻的 global CheckpointTS 作为 Primary Ts 插入下游的 TiDB 记录 tsMap 信息的表中,然后 TiCDC 才会继续向下游同步数据。 + 2. 修改集群配置文件中 TiCDC 组件的镜像版本为新架构版本。 -一个 Barrier TS 被生成后, TiCDC 会保证只有小于 Barrier TS 的数据会被复制到下游,并且保证小于 Barrier TS 的数据全部被复制到下游之前,同步任务不会再推进。Owner 不断地比较 global CheckpointTS 和 Barrier TS 的大小,确定小于 Barrier TS 的数据是否已经被同步完成。如果 global CheckpointTS = Barrier TS,执行完对应的操作(如 DDL 或者记录 global CheckpointTS 到下游)后,同步继续;否则需要继续等待所有小于 Barrier TS 数据的同步完成。 + ```shell + kubectl edit tc ${cluster_name} -n ${namespace} + ``` -## 主要流程 + ```yaml + spec: + ticdc: + baseImage: pingcap/ticdc + version: v8.5.4-release.1 + replicas: 3 + ``` -本章节将介绍 TiCDC 软件的常见操作所对应的主要流程,以帮助你更好的理解 TiCDC 的工作原理。 + ```shell + kubectl apply -f ${cluster_name} -n ${namespace} + ``` -注意,下面所描述的启动流程只存在于 TiCDC 进程内部,对于用户是完全透明的。因此,你在启动 TiCDC 进程时无需关心自己启动的是什么节点。 + 3. 恢复所有的 Changefeed 同步任务。 -### 启动 TiCDC 节点 + ```shell + kubectl exec -it ${pod_name} -n ${namespace} -- sh + ``` -- 启动非 Owner 的 TiCDC 节点: + ```shell + # 通过 TiDB Operator 部署的 TiCDC 服务器的默认端口为 8301 + /cdc cli changefeed resume --server=http://127.0.0.1:8301 --changefeed-id + ``` - 1. 启动 Capture 进程。 - 2. 启动 processor。 - 3. 接收 Owner 下发的 Task 调度命令。 - 4. 根据调度命令启动或停止 tablePipeline。 +
+
-- 启动 Owner 的 TiCDC 节点: +## 使用指南 + +在 TiCDC 新架构的节点部署完成后,即可使用相应的命令进行操作。新架构沿用了旧架构的 TiCDC 使用方式,因此无需额外学习新的命令,也无需修改旧架构中使用到的命令。 + +例如,要在新架构的 TiCDC 节点中创建同步任务,可执行以下命令: + +```shell +cdc cli changefeed create --server=http://127.0.0.1:8300 --sink-uri="mysql://root:123456@127.0.0.1:3306/" --changefeed-id="simple-replication-task" +``` + +若需查询特定同步任务的信息,可执行: + +```shell +cdc cli changefeed query -s --server=http://127.0.0.1:8300 --changefeed-id=simple-replication-task +``` - 1. 启动 Capture 进程。 - 2. 当选 Owner 并启动对应的线程。 - 3. 读取 Changefeed 信息。 - 4. 启动 Changefeed 管理逻辑。 - 5. 根据 Changefeed 配置和最新 CheckpointTS,读取 TiKV 中的 schema 信息,确定需要被同步的表。 - 6. 读取各 Processor 当前同步的表的列表,分发需要添加的表。 - 7. 更新进度信息。 +更多命令的使用方法和细节,可以参考[管理 Changefeed](/ticdc/ticdc-manage-changefeed.md)。 -### 停止 TiCDC 节点 +## 监控 -通常来说,停止 TiCDC 节点是为了对 TiCDC 进行升级,或者对 TiCDC 所在的节点进行一些计划的维护操作。停止 TiCDC 节点的流程如下: +目前,TiUP 尚未集成 TiCDC 新架构的监控面板 **TiCDC-New-Arch**。要在 Grafana 中查看该面板,你需要手动导入 [TiCDC 监控指标文件](https://github.com/pingcap/ticdc/blob/master/metrics/grafana/ticdc_new_arch.json)。 -1. 节点收到停止的信号。 -2. 节点将自己的服务状态置为不可用状态。 -3. 节点停止接收新的复制表任务。 -4. 通知 Owner 节点将自己节点的数据复制任务转移到其他节点。 -5. 复制任务转移到其他节点后,该节点停止完成。 +各监控指标的详细说明,请参考 [TiCDC 新架构监控指标](/ticdc/monitor-ticdc.md#ticdc-新架构监控指标)。 \ No newline at end of file diff --git a/ticdc/ticdc-classic-architecture.md b/ticdc/ticdc-classic-architecture.md new file mode 100644 index 000000000000..0cd5c9aab836 --- /dev/null +++ b/ticdc/ticdc-classic-architecture.md @@ -0,0 +1,182 @@ +--- +title: TiCDC 老架构设计与原理 +summary: 了解 TiCDC 老架构的设计和运行原理。 +--- + +# TiCDC 老架构 + +本文档介绍了 TiCDC 老架构的设计与工作原理。 + +> **注意:** +> +> - 该文档适用于 TiCDC v8.5.4-release.1 之前的 TiCDC 版本。 +> - 从 TiCDC v8.5.4-release.1 开始,TiCDC 引入了全新架构,在提升实时数据复制性能、可扩展性及稳定性的同时,有效降低了资源成本。更多信息,请参阅 [TiCDC 新架构](/ticdc/ticdc-architecture.md)。 + +## TiCDC 老架构介绍 + +TiCDC 集群由多个 TiCDC 对等节点组成,是一种分布式无状态的架构设计。TiCDC 集群及节点内部组件的设计如下图所示: + +![TiCDC architecture](/media/ticdc/ticdc-architecture-1.jpg) + +## 组件介绍 + +上图中,TiCDC 集群由多个运行了 TiCDC 实例的节点组成,每个 TiCDC 实例都运行一个 Capture 进程。多个 Capture 进程中会有一个被选举成为 Owner Capture,负责完成 TiCDC 集群的负载调度、DDL 语句同步和其它管理任务。 + +每个 Capture 进程包含一个或多个 Processor 线程,用于同步上游 TiDB 集群中的表数据。由于 TiCDC 同步数据的最小单位是表,所以 Processor 是由多条 table pipeline 构成的。 + +每条 pipeline 包含 Puller、Sorter、Mounter 和 Sink 模块,如下图。 + +![TiCDC architecture](/media/ticdc/ticdc-architecture-2.jpg) + +各个模块之间是串行的关系,组合在一起完成从上游拉取、排序、加载和同步数据到下游的过程,其中: + +- Puller:从 TiKV 节点获取 DDL 和行变更信息。 +- Sorter:将接收到的变更在 TiCDC 内按照时间戳进行升序排序。 +- Mounter:将变更按照对应的 Schema 信息转换成 TiCDC 可以处理的格式。 +- Sink:将对应的变更应用到下游系统。 + +为了实现高可用,每个 TiCDC 集群都包含多个 TiCDC 节点,这些节点定期向 PD 集群中的 etcd 集群汇报自己的状态,并选举出其中一个节点作为 TiCDC 集群的 Owner。Owner 采用 etcd 统一存储状态来进行调度,并将调度结果直接写入 etcd。Processor 按照状态完成对应的任务,如果 Processor 所在节点出现异常,集群会将表调度到其他节点。如果 Owner 节点出现异常,其他节点的 Capture 进程会选举出新的 Owner,如下图所示: + +![TiCDC architecture](/media/ticdc/ticdc-architecture-3.PNG) + +## Changefeed 和 Task + +TiCDC 中的 Changefeed 和 Task 是两个逻辑概念,前者是分配同步任务的方式,后者是同步任务拆分后的子任务名称,具体描述如下: + +- Changefeed:代表一个同步任务,携带了需要同步的表信息,以及对应的下游信息和一些其他的配置信息。 + +- Task:当 TiCDC 接收到对应的同步任务之后,就会把这个任务拆分为若干个称之为 Task 的子任务,分配给 TiCDC 集群的各个节点上的 Capture 进程进行处理。 + +例如: + +``` +cdc cli changefeed create --server="http://127.0.0.1:8300" --sink-uri="kafka://127.0.0.1:9092/cdc-test?kafka-version=2.4.0&partition-num=6&max-message-bytes=67108864&replication-factor=1" +cat changefeed.toml +...... +[sink] +dispatchers = [ + {matcher = ['test1.tab1', 'test2.tab2'], topic = "{schema}_{table}"}, + {matcher = ['test3.tab3', 'test4.tab4'], topic = "{schema}_{table}"}, +] +``` + +关于命令中参数的详细释义,参考 [TiCDC Changefeed 配置参数](/ticdc/ticdc-changefeed-config.md)。 + +以上命令创建了一个到 Kafka 集群的 Changefeed 任务,需要同步 `test1.tab1`、`test1.tab2`、`test3.tab3` 和 `test4.tab4` 四张表。TiCDC 接收到这个命令之后的处理流程如下: + +1. TiCDC 将这个任务发送给 Owner Capture 进程。 +2. Owner Capture 进程将这个任务的相关定义信息保存在 PD 的 etcd 中。 +3. Owner Capture 将这个任务拆分成若干个 Task,并通知其他 Capture 进程各个 Task 需要完成的任务。 +4. 各个 Capture 进程开始从对应的 TiKV 节点拉取信息,进行处理后完成同步。 + +如果将 Changefeed 和 Task 也包含到上文中提及的架构图,完整的 TiCDC 架构图如下: + +![TiCDC architecture](/media/ticdc/ticdc-architecture-6.jpg) + +上图创建了一个 Changefeed,需要同步 4 张表,这个 Changefeed 被拆分成了 3 个任务,均匀的分发到了 TiCDC 集群的 3 个 Capture 节点上,在 TiCDC 对这些数据进行了处理之后,数据同步到了下游的系统。 + +目前 TiCDC 支持的下游系统包含 MySQL、TiDB 和 Kafka。上面的过程只是讲解了 Changefeed 级别数据流转的基本过程,接下来,本文将以处理表 `table1` 的任务 Task1 为例,从更加详细的层面来描述 TiCDC 处理数据的过程: + +![TiCDC architecture](/media/ticdc/ticdc-architecture-5.jpg) + +1. 推流:发生数据改变时,TiKV 集群将数据主动推送给 Puller 模块。 +2. 增量扫:Puller 模块在发现收到的数据改变不连续的时候,向 TiKV 节点主动拉取需要的数据。 +3. 排序:Sorter 模块对获取的数据按照时间进行排序,并将排好序的数据发送给 Mounter。 +4. 装载:Mounter 模块收到数据变更后,根据表的 schema 信息,将数据变更装载成 TiCDC sink 可以理解的格式。 +5. 同步:Sink 模块根据下游的类型将数据变更同步到下游。 + +由于 TiCDC 的上游是支持事务的分布式关系型数据库 TiDB,在同步数据的时候,如何保证数据的一致性,以及在同步多张表的时候,如何保证事务的一致性,都是很大的挑战。下面的章节会介绍 TiCDC 在确保事务特性时所使用的关键技术和概念。 + +## TiCDC 关键概念 + +当 TiCDC 对应的下游系统是关系型数据库时,TiCDC 在同步数据的时候会确保单表事务的数据一致性,以及多表事务的最终一致性。另外,TiCDC 会确保上游 TiDB 集群发生过的数据变更能够被 TiCDC 向任意下游最少同步一次。 + +### 架构相关概念 + +- Capture:TiCDC 节点的运行进程,多个 Capture 进程构成了 TiCDC 集群,Capture 进程负责 TiKV 的数据变更的同步,包括接收和主动拉取两种方式,并向下游同步数据。 +- Capture Owner:是一种 Capture 的角色,每个 TiCDC 集群同一时刻最多只存在一个 Capture Owner 角色,负责集群内部的调度。 +- Processor:是 Capture 内部的逻辑线程,每个 Processor 负责处理同一个同步流中一个或多个 table 的数据。一个 Capture 节点可以运行多个 Processor。 +- ChangeFeed:一个由用户启动的从上游 TiDB 同步到下游的任务,其中包含多个 Task,Task 会分布在不同的 Capture 节点进行数据同步处理。 + +### 时间戳相关概念 + +由于 TiCDC 需要确保数据被至少一次同步到下游,并且确保一定的一致性,因此引入了一系列时间戳(Timestamp,简称 TS)来对数据同步的状态进行描述。 + +#### ResolvedTS + +这个时间戳在 TiKV 和 TiCDC 中都存在。 + +- TiKV 节点中的 ResolvedTS:代表某一个 Region leader 上开始时间最早的事务的开始时间,即:ResolvedTS = max(ResolvedTS, min(StartTS))。因为每个 TiDB 集群包含多个 TiKV 节点,所有 TiKV 节点上的 Region leader 的 ResolvedTS 的最小值,被称为 Global ResolvedTS。TiDB 集群确保 Global ResolvedTS 之前的事务都被提交了,或者可以认为这个时间戳之前不存在未提交的事务。 + +- TiCDC 节点中的 ResolvedTS: + + - table ResolvedTS:每张表都会有的表级别 ResolvedTS,表示这张表已经从 TiKV 接收到的数据改变的最低水位,可以简单的认为和 TiKV 节点上这张表的各个 Region 的 ResolvedTS 的最小值是相同的。 + - global ResolvedTS:各个 TiCDC 节点上的 Processor ResolvedTS 的最小值。由于 TiCDC 每个节点上都会存在一个或多个 Processor,每个 Processor 又对应多个 table pipeline。 + + 对于 TiCDC 节点来说,TiKV 节点发送过来的 ResolvedTS 信息是一种特殊的事件,它只包含一个格式为 `` 的特殊事件。通常情况下,ResolvedTS 满足以下约束: + + ``` + table ResolvedTS >= global ResolvedTS + ``` + +#### CheckpointTS + +这个时间戳只在 TiCDC 中存在,它表示 TiCDC 已经同步给下游的数据的最低水位线,即 TiCDC 认为在这个时间戳之前的数据已经被同步到下游系统了。由于 TiCDC 同步数据的单位是表,所以 table CheckpointTS 表示表级别的同步数据的水位线,Processor CheckpointTS 表示各个 Processor 中最小的 table CheckpointTS;Global checkpointTS 表示各个 Processor checkpointTS 中最低的 checkpointTS。通常情况下,Checkpoint TS 满足以下约束: + +``` +table CheckpointTS >= global CheckpointTS +``` + +因为 TiCDC 只会复制小于 global ResolvedTS 的数据到下游,所以存在下面的约束: + +``` +table ResolvedTS >= global ResolvedTS >= table CheckpointTS >= global CheckpointTS +``` + +随着数据的改变和事务的提交,TiKV 节点上的 ResolvedTS 会不断的向前推进,TiCDC 节点的 Puller 模块也会不断的收到 TiKV 推流过来的数据,并且根据收到的信息决定是否执行增量扫的过程,从而确保数据改变都能够被发送到 TiCDC 节点上。Sorter 模块则负责将 Puller 模块收到的信息按照时间戳进行升序排序,从而确保数据在表级别是满足一致性的。接下来,Mounter 模块把上游的数据改变装配成 Sink 模块可以消费的格式,并发送给 Sink,而 Sink 则负责把 CheckpointTS 到 ResolvedTS 之间的数据改变,按照发生的 TS 顺序同步到下游,并在下游返回后推进 CheckpointTS。 + +上面的内容只介绍了和 DML 语句相关的数据改变,并没有包含 DDL 相关的内容。下面对 DDL 语句相关的关键概念进行介绍。 + +#### Barrier TS + +当系统发生 DDL 变更或者用户使用了 TiCDC 的 Syncpoint 时会产生的一个时间戳。 + +- DDL:这个时间戳会用来确保在这个 DDL 语句之前的改变都被应用到下游,之后执行对应的 DDL 语句,在 DDL 语句同步完成之后再同步其他的数据改变。由于 DDL 语句的处理是 Owner 角色的 Capture 负责的,DDL 语句对应的 Barrier TS 只会由 Owner 节点产生。 +- Syncpoint:当你启用 TiCDC 的 Syncpoint 特性后,TiCDC 会根据你指定的间隔产生一个 Barrier TS。等所有表都同步到这个 Barrier TS 后,TiCDC 将此刻的 global CheckpointTS 作为 Primary Ts 插入下游的 TiDB 记录 tsMap 信息的表中,然后 TiCDC 才会继续向下游同步数据。 + +一个 Barrier TS 被生成后, TiCDC 会保证只有小于 Barrier TS 的数据会被复制到下游,并且保证小于 Barrier TS 的数据全部被复制到下游之前,同步任务不会再推进。Owner 不断地比较 global CheckpointTS 和 Barrier TS 的大小,确定小于 Barrier TS 的数据是否已经被同步完成。如果 global CheckpointTS = Barrier TS,执行完对应的操作(如 DDL 或者记录 global CheckpointTS 到下游)后,同步继续;否则需要继续等待所有小于 Barrier TS 数据的同步完成。 + +## 主要流程 + +本章节将介绍 TiCDC 软件的常见操作所对应的主要流程,以帮助你更好的理解 TiCDC 的工作原理。 + +注意,下面所描述的启动流程只存在于 TiCDC 进程内部,对于用户是完全透明的。因此,你在启动 TiCDC 进程时无需关心自己启动的是什么节点。 + +### 启动 TiCDC 节点 + +- 启动非 Owner 的 TiCDC 节点: + + 1. 启动 Capture 进程。 + 2. 启动 processor。 + 3. 接收 Owner 下发的 Task 调度命令。 + 4. 根据调度命令启动或停止 tablePipeline。 + +- 启动 Owner 的 TiCDC 节点: + + 1. 启动 Capture 进程。 + 2. 当选 Owner 并启动对应的线程。 + 3. 读取 Changefeed 信息。 + 4. 启动 Changefeed 管理逻辑。 + 5. 根据 Changefeed 配置和最新 CheckpointTS,读取 TiKV 中的 schema 信息,确定需要被同步的表。 + 6. 读取各 Processor 当前同步的表的列表,分发需要添加的表。 + 7. 更新进度信息。 + +### 停止 TiCDC 节点 + +通常来说,停止 TiCDC 节点是为了对 TiCDC 进行升级,或者对 TiCDC 所在的节点进行一些计划的维护操作。停止 TiCDC 节点的流程如下: + +1. 节点收到停止的信号。 +2. 节点将自己的服务状态置为不可用状态。 +3. 节点停止接收新的复制表任务。 +4. 通知 Owner 节点将自己节点的数据复制任务转移到其他节点。 +5. 复制任务转移到其他节点后,该节点停止完成。 diff --git a/ticdc/ticdc-overview.md b/ticdc/ticdc-overview.md index 91c5f87edad7..2e969ba9b493 100644 --- a/ticdc/ticdc-overview.md +++ b/ticdc/ticdc-overview.md @@ -52,7 +52,7 @@ TiCDC 提供了以下核心能力: > > 从 v6.2 版本起,你可以通过配置 sink URI 参数 [`transaction-atomicity`](/ticdc/ticdc-sink-to-mysql.md#sink-uri-配置-mysqltidb) 来控制 TiCDC 是否拆分单表事务。拆分事务可以大幅降低 MySQL sink 同步大事务的延时和内存消耗。 -## TiCDC 架构 +## TiCDC 架构概览 TiCDC 作为 TiDB 的增量数据同步工具,通过 PD 内部的 etcd 实现高可用,通过多个 TiCDC 进程获取 TiKV 节点上的数据改变,在内部进行排序、合并等处理之后,通过多个同步任务 (Changefeed),同时向多个下游系统进行数据同步。 @@ -64,6 +64,8 @@ TiCDC 作为 TiDB 的增量数据同步工具,通过 PD 内部的 etcd 实现 - TiCDC:代表运行了 TiCDC 进程的各个节点。每个节点都运行一个 TiCDC 进程,每个进程会从 TiKV 节点中拉取一个或者多个表中的数据改变,并通过 Sink 模块同步到下游系统。 - PD:代表 TiDB 集群中的调度模块,负责集群数据的事实调度,这个模块通常是由 3 个 PD 节点构成的,内部通过 etcd 集群来实现选举等高可用相关的能力。 TiCDC 集群使用了 PD 集群内置的 etcd 集群来保存自己的元数据信息,例如:节点的状态信息,changefeed 配置信息等。 +在具体实现上,TiCDC 的[新架构](/ticdc/ticdc-architecture.md)和[老架构](/ticdc/ticdc-classic-architecture.md)均基于上述模型实现增量数据同步。相比之下,新架构在任务调度和同步机制上进行了重构与优化,显著提升了实时数据复制的性能、可扩展性与稳定性,同时降低了资源成本。 + 另外,从上面的架构图中也可以看到,目前 TiCDC 支持将数据同步到 TiDB、MySQL 数据库、Kafka 以及存储服务等。 ## 有效索引 @@ -146,6 +148,6 @@ WHERE `A` = 1 OR `A` = 2; - 暂不支持在 TiDB 中[创建 SEQUENCE 的 DDL 操作](/sql-statements/sql-statement-create-sequence.md)和 [SEQUENCE 函数](/sql-statements/sql-statement-create-sequence.md#sequence-函数)。在上游 TiDB 使用 SEQUENCE 时,TiCDC 将会忽略掉上游执行的 SEQUENCE DDL 操作/函数,但是使用 SEQUENCE 函数的 DML 操作可以正确地同步。 - 暂不支持对 TiCDC 正在同步的表和库进行 [TiDB Lightning 物理导入](/tidb-lightning/tidb-lightning-physical-import-mode.md)。详情请参考[为什么在上游使用了 TiDB Lightning 和 BR 恢复了数据之后,TiCDC 同步会出现卡顿甚至卡住](/ticdc/ticdc-faq.md#为什么在上游使用了-tidb-lightning-物理导入模式和-br-恢复了数据之后ticdc-同步会出现卡顿甚至卡住)。 - 在 BR v8.2.0 之前的版本中,当集群存在 TiCDC 同步任务时,BR 不支持进行[数据恢复](/br/backup-and-restore-overview.md)。详情请参考[为什么在上游使用了 TiDB Lightning 和 BR 恢复了数据之后,TiCDC 同步会出现卡顿甚至卡住](/ticdc/ticdc-faq.md#为什么在上游使用了-tidb-lightning-物理导入模式和-br-恢复了数据之后ticdc-同步会出现卡顿甚至卡住)。 -- 从 BR v8.2.0 起,BR 数据恢复对 TiCDC 的限制被放宽:如果所恢复数据的 BackupTS(即备份时间)早于 Changefeed 的 [CheckpointTS](/ticdc/ticdc-architecture.md#checkpointts)(即记录当前同步进度的时间戳),BR 数据恢复可以正常进行。考虑到 BackupTS 通常较早,此时可以认为绝大部分场景下,当集群存在 TiCDC 同步任务时,BR 都可以进行数据恢复。 +- 从 BR v8.2.0 起,BR 数据恢复对 TiCDC 的限制被放宽:如果所恢复数据的 BackupTS(即备份时间)早于 Changefeed 的 [CheckpointTS](/ticdc/ticdc-classic-architecture.md#checkpointts)(即记录当前同步进度的时间戳),BR 数据恢复可以正常进行。考虑到 BackupTS 通常较早,此时可以认为绝大部分场景下,当集群存在 TiCDC 同步任务时,BR 都可以进行数据恢复。 对上游存在较大事务的场景提供部分支持,详见 [TiCDC 是否支持同步大事务?有什么风险吗?](/ticdc/ticdc-faq.md#ticdc-支持同步大事务吗有什么风险吗)。 diff --git a/ticdc/ticdc-server-config.md b/ticdc/ticdc-server-config.md index f447691a8cf6..07c35cf5ecce 100644 --- a/ticdc/ticdc-server-config.md +++ b/ticdc/ticdc-server-config.md @@ -30,6 +30,12 @@ summary: 了解 TiCDC 详细的命令行参数和配置文件定义。 对于 `cdc server` 命令中 `config` 参数指定的配置文件说明如下。你可以在 [`pkg/cmd/util/ticdc.toml`](https://github.com/pingcap/tiflow/blob/master/pkg/cmd/util/ticdc.toml) 找到默认值的配置文件。 +### `newarch` 从 v8.5.4-release.1 版本开始引入 + +- 控制是否开启 [TiCDC 新架构](/ticdc/ticdc-architecture.md)。 +- 默认值:`false`,表示使用 [TiCDC 老架构](/ticdc/ticdc-classic-architecture.md)。 +- 当设置为 `true` 时,表示开启 TiCDC 新架构。 + ### `addr`