ClickPipes 背后的技术实现:在 ClickHouse 中构建 MySQL 变更数据捕获

图片

本文字数:4437;估计阅读时间:12 分钟

作者:Kaushik Iska, Philip Dubé

图片

简介

变更数据捕获(Change Data Capture,CDC)是现代数据架构中实现实时数据集成的重要技术模式。本文将深入探讨 ClickPipes —— ClickHouse Cloud 提供的原生数据集成方案 —— 如何在内部实现对 MySQL 数据库的 CDC。文章面向工程师与架构师,旨在帮助读者深入理解这一高可靠、高性能数据库复制机制背后的工作原理。

MySQL 复制基础

我们先回顾一下 MySQL 中的复制基本原理。

二进制日志:MySQL CDC 的核心

MySQL 的二进制日志(binlog)是其整个复制架构的基础。它会按顺序记录所有对数据库数据和结构所做的更改,概念图如下:

图片

这些日志事件包括:

  • 数据操作(INSERT、UPDATE、DELETE)

  • 数据定义(CREATE、ALTER、DROP)

  • 事务边界(BEGIN、COMMIT、ROLLBACK)

每个 binlog 事件都包含一个事件头(包含时间戳、服务器 ID 等元数据),以及一个事件体,记录实际的数据变更内容。

二进制日志格式

MySQL 支持三种 binlog 格式:

  1. STATEMENT:记录执行的 SQL 语句

    1. 日志数据量小

    1. 遇到非确定性函数时可能导致复制不一致

    1. 不适用于 CDC 场景

  2. ROW:记录实际变更的行数据

    1. 包含变更前和变更后的行镜像

    1. 数据最精确,但日志体积较大

    1. 是实现 CDC 所必须的格式

  3. MIXED:默认采用 STATEMENT 格式,在需要时切换为 ROW 格式

    1. 同样不适用于 CDC

前提条件 — binlog_row_image = FULL

为了保证每次行级变更都能携带完整的变更前和变更后镜像,ClickPipes 要求源 MySQL 数据库将参数 binlog_row_image 设置为 'FULL'。这是 MySQL 8.x 中的默认配置。虽然 MINIMAL 或 NOBLOB 等轻量模式可以省略未发生变化的列,从而减少日志体积,但这会影响 ClickPipes 的幂等更新能力,并可能导致主键更新操作不安全。启用 FULL 模式主要会增加包含大量 UPDATE 的日志大小,而 INSERT 和 DELETE 基本不受影响,因此整体性能开销通常可控。

全局事务标识符(GTID)

GTID(Global Transaction Identifiers)提供了一种在多台服务器之间统一标识事务的方法:

GTID = source_id:transaction_id

示例 GTID 集:123e4567-e89b-12d3-a456-426614174000:1-1000,2000-3000

基于 GTID 的复制具有以下优势:

  • 即使服务器重启,也能持续追踪事务

  • 简化故障转移流程,实现高可用

  • 支持灵活调整复制拓扑结构

ClickPipes MySQL CDC 架构

ClickPipes 使用一套稳定可靠的架构来支持对 MySQL 的变更数据捕获,既支持初始化加载,也支持持续复制。

架构概览

下图展示了 ClickPipes 中 MySQL CDC 的架构组成:

图片

这条 CDC 数据通道主要包括以下几个核心组件:

  1. 连接管理模块:负责与源 MySQL 数据库建立并维护连接

  2. Binlog 同步器:持续监听并同步 MySQL 的二进制日志流

  3. 事件处理器:将 binlog 中的事件解析为结构化的变更记录

  4. 表结构注册中心:跟踪和管理源端表的结构变更

  5. 检查点机制:记录处理进度,以便故障恢复时能够断点续传

  6. 类型转换层:将 MySQL 中的数据类型转换为 ClickHouse 兼容类型

  7. 写入模块:将变更数据高效写入 ClickHouse

连接与配置初始化

在启动 MySQL 的 CDC 流程时,ClickPipes 会执行一系列初始化操作,包括:

  1. 校验 MySQL 的相关配置是否符合要求

    1. 确保 binlog_format 被设置为 'ROW'

    1. 检查 binlog_row_image 是否为 'FULL'

    1. 验证二进制日志的保留时间设置

  2. 确认数据库是否启用了复制功能

    1. 检测是否支持 GTID 模式

    1. 确定起始的复制位置

  3. 提取源表的结构信息

    1. 获取每个字段的定义和数据类型

    1. 识别主键列

    1. 将 MySQL 的数据类型映射为 ClickHouse 的对应类型

初始数据加载

在开始实时变更同步之前,ClickPipes 会先进行一次初始快照操作:

图片

  • 创建一份数据的一致性快照

  • 在 ClickHouse 中创建相应的目标表

  • 记录当前的 binlog 位置或 GTID 作为后续变更流的起点

变更数据流

初始数据加载完成后,ClickPipes 会开始持续同步 MySQL 的数据变更:

图片

  1. 建立与 MySQL binlog 流的连接

  2. 按照事务顺序处理变更事件

  3. 将行级事件解析为结构化的变更记录

  4. 将这些变更应用到 ClickHouse 中

  5. 持续更新检查点,以记录处理进度并支持容错恢复

基于 GTID 与 Binlog 位置的复制

ClickPipes 同时支持两种复制方式:

基于 GTID 的复制

GTID(全局事务标识符)为事务追踪提供了一种逻辑一致的方式。当一个事务提交后,GTID 集合会被更新并写入检查点,从而实现高效的断点续传,具备较强的容错能力,可适应服务器重启或拓扑结构调整等变化。

基于 Binlog 位置的复制

传统方式通过文件名和偏移位置标记复制进度。当 binlog 日志轮转时,系统会记录新的文件名及其位置。这种方式虽然有效,但在面对服务器变更和高可用场景时灵活性较差,一旦发生故障切换,通常需要重新初始化复制任务。

处理二进制日志事件

ClickPipes 能识别并处理多种类型的 binlog 事件:

行级变更事件

图片

CDC 流水线会处理以下操作:

  1. INSERT:提取列数据,生成插入记录

  2. UPDATE:捕获修改前后的值,生成更新记录

  3. DELETE:提取被删除的数据,生成删除记录

表结构变更事件

系统通过解析 DDL 语句检测并同步表结构的变化,具体包括:

  1. 利用 TiDB 的 SQL 解析器解析 DDL

  2. 提取结构变更(如新增列)

  3. 更新内部的结构注册表

  4. 将变更同步到 ClickHouse 的目标表中

类型映射与转换

ClickPipes 支持完整的 MySQL 数据类型,并对复杂情况做了额外处理,包括:

图片

会话系统用如下方式来处理边界情况:

  • Enum 和 Set 类型值的映射(依赖 binlog_row_metadata)

  • 二进制数据的解析和写入支持

性能优化机制

为了实现高效的 CDC 处理,ClickPipes 实施了以下优化措施:

事务级批处理

系统按事务对变更进行批量处理,以保持数据一致性,同时允许用户设置批处理的大小。

空闲检测

系统具备空闲检测能力,能在无数据流动的情况下及时释放资源,防止资源浪费。

并行处理机制

ClickPipes 在多个关键环节实现了并行处理,包括:

  • 并行拉取表结构信息

  • 批量处理表数据

  • 并发写入 ClickHouse

智能重试策略

系统采用指数退避机制进行自动重试,可有效应对临时性失败,提升整体稳定性。

监控与可观测性

ClickPipes 提供了全面的 CDC 监控指标,便于用户掌握运行状态,包括:

  • 每秒处理记录数

  • 从 binlog 读取的数据量

  • 复制延迟时间

  • 错误率统计

  • 当前复制位置或 GTID 信息

故障处理机制

ClickPipes 针对各种异常场景构建了完善的容错策略:

连接故障

系统内置重试机制,在网络故障时自动恢复连接,确保同步不中断。

结构不一致

系统能够检测源表与目标表之间的结构差异,并及时报告,避免因结构偏差导致数据写入错误。

故障恢复

借助检查点机制,系统在失败后能够自动恢复同步,确保数据不丢失、不重复。

开源社区贡献

在实现 ClickPipes 的 MySQL CDC 功能过程中,我们对关键依赖库进行了优化和扩展,特别是对 go-mysql-org/go-mysql 项目做出了如下贡献:

  • 增加对 MariaDB 认证方式的支持

  • 引入基于 log/slog 的现代日志系统

  • 实现位运算层级优化,提升整体性能

  • 添加对 SQL driver 的上下文管理能力

  • 支持 MySQL 向量类型

这些开源贡献为 ClickPipes 提供了强健、可维护的复制基础。

最佳实践

为了让 ClickPipes 实现更优的 MySQL CDC 性能,建议遵循以下最佳实践:

  1. MySQL 配置建议

    1. 将 binlog_format = 'ROW'  

    1. 设置 binlog_row_image = 'FULL'  

    1. 设置 binlog_row_metadata = 'FULL',以支持列级过滤、防止因源端忽略列导致的同步问题,并增强对 enum/set 类型的支持  

    1. 设置合理的 binlog 保留时间,建议不少于 24 小时  

  2. 表设计优化

    1. 所有表应配置主键  

    1. 在变更频繁的表中避免使用大型对象字段(如 BLOB)  

    1. 对于数据量大的表,建议进行合理分区  

  3. 网络通信优化

    1. 优先将 ClickPipes 与 MySQL 部署在同一网络区域  

    1. 使用 VPC 对等连接或专用网络链路提升传输效率  

    1. 启用 TLS 加密保障数据传输的安全性  

  4. 运行监控建议

    1. 实时跟踪复制延迟  

    1. 监控 binlog 的增长速率  

    1. 配置复制延迟的告警策略,及时响应异常情况  

性能与基准测试

我们即将发布 ClickPipes MySQL CDC 的全面性能评估报告。根据目前的初步测试结果,该系统在处理多样化工作负载(包括高频小型事务、大规模批量写入,以及真实的混合型场景)中均表现出色。在理想环境下,每秒可处理数万条数据变更,整体同步延迟控制在 30 秒以内。

已知限制与边界情况

在使用 ClickPipes MySQL CDC 时,请注意以下限制:

  1. 结构变更支持

    1. 完全支持新增列操作  

    1. 对列的删除和重命名操作可识别,但不会自动应用到目标表  

    1. 表名变更需要用户手动介入  

  2. 数据类型限制

    1. 二进制字段需要满足大小限制要求  

  3. 复制配置要求

    1. 必须启用并正确设置二进制日志功能  

    1. 需要具有足够的数据库权限以读取 binlog  

    1. 表需配置主键以确保同步性能  

  4. 当前不支持 TRUNCATE 操作  

结语

ClickPipes 提供了一套健壮且高效的 MySQL CDC 实现方案,能够稳定捕获并实时同步 MySQL 数据库中的变更内容。系统基于 MySQL 原生的复制能力,结合智能的数据处理流水线,实现了与 ClickHouse 的高效数据集成。

ClickPipes 的架构设计兼顾可靠性、性能和使用简便性,适用于运营型数据库同步、实时分析和数据湖建设等多种场景。深入理解其内部机制,能够帮助用户更好地优化数据流转路径,并快速定位与排查潜在问题。

如需了解 ClickPipes MySQL CDC 的更多使用细节,请参阅官方文档。目前该功能已进入私有预览阶段,欢迎申请体验。

征稿启示

面向社区长期正文,文章内容包括但不限于关于 ClickHouse 的技术研究、项目实践和创新做法等。建议行文风格干货输出&图文并茂。质量合格的文章将会发布在本公众号,优秀者也有机会推荐到 ClickHouse 官网。请将文章稿件的 WORD 版本发邮件至:Tracy.Wang@clickhouse.com

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值