跳到主要内容

28 篇博文 含有标签「技术分享」

Tech share

查看所有标签

Kafka vs RabbitMQ vs RocketMQ vs Pulsar:四大开源消息中间件全面对比

· 阅读需 6 分钟
John Li
John Li
Chief Executive Officer

消息中间件应用广泛,KafkaRabbitMQRocketMQPulsar 更是其中的佼佼者,经常被放在一起比较。

从数据迁移同步行业来看,Kafka 用户占了大多数,因为在大数据生态中,其是核心组件之一。RocketMQ 在国内也比较流行,主要应用在在线业务场景,这和它的技术特性和发展路径紧密相关。相比之下,RabbitMQ 和 Pulsar 的使用量在国内相对少些。

那么,它们到底有什么区别呢?本文将从架构设计、性能表现、可扩展性、可靠性 4 个角度进行对比,以呈现一个相对客观的产品状态。

架构设计

Kafka

Kafka 采用分布式日志存储架构。Producer 将消息写入 Broker,Broker 将消息存储在分区日志中,Consumer 从分区中顺序拉取数据。ZooKeeper 管理集群元数据。

RabbitMQ

RabbitMQ 基于 AMQP 协议。Producer 将消息发送到 Exchange,再由 Exchange 根据路由规则将消息投递到不同 Queue,最终由 Consumer 消费。其路由模式(direct/topic/fanout/headers)非常灵活,便于应对复杂消息流转。

RocketMQ

RocketMQ 采用轻量级 NameServer + Broker 架构,Producer 从 NameServer 获取路由信息,再将消息写入 Broker 的队列(MessageQueue)。支持事务消息、顺序消息。

Pulsar

Pulsar 采用 Broker + BookKeeper(存储层)架构,实现计算与存储分离。支持分层存储,天然云原生。

性能表现

指标KafkaRabbitMQRocketMQPulsar
吞吐量单节点可达 数十万–百万 TPS,集群扩展后可达 百万级 TPS+单节点约 万级 TPS,高并发下易受限单节点 数十万 TPS,集群可扩展到百万级(双十一场景)单节点 数十万 TPS,大规模集群可达 百万级+
消息延迟通常 数十毫秒毫秒级,在高吞吐量情况下延迟增大通常几十毫秒通常 几十毫秒
消息堆积能力天然支持海量堆积与历史回放(磁盘持久化,分区日志)不适合长时间、大规模堆积,内存压力大支持长时间堆积基于 BookKeeper,多副本存储,支持大规模堆积与分层存储

注:数据仅供参考,权威 benchmark 参见产品官方资料

可扩展性

Kafka基于 分区(Partition) 实现水平扩展,一个 Topic 可以拆分为多个分区并行处理。Broker 集群内的节点数量可扩展至成百上千,支撑大规模实时数据流。

RabbitMQ通过 多节点集群 模式扩展,但 Queue 需要复制到多个节点,带来较高的同步开销。因此更适合中等规模数据场景。

RocketMQ通过 增加 Broker 和队列数量 提升性能,存储层支持动态增加 Broker,消费者也能独立扩展,可无停机进行扩容。对于大规模分布式系统,RocketMQ 的扩展方式比较友好。

Pulsar采用 存算分离,可以单独增加 Broker 提升处理能力,增加 BookKeeper 提升存储能力,互不影响,再加上多租户动态资源分配,适合 大规模云原生环境

可靠性

Kafka依靠 分区多副本 机制保证数据安全。默认提供 At-least-once 语义,通过幂等写入和事务机制可以实现 Exactly-once。

RabbitMQ3.8.0 版本中引入了 Quorum Queue,基于 Raft 共识算法,增强可靠性。提供 At-least-once 语义,保证不丢消息,但可能存在重复,需要业务端做幂等处理。

RocketMQ通过 主从复制刷盘机制 保证可靠性。新版本的 DLedger 基于 Raft 协议,支持自动主从切换,容错能力更强。

Pulsar基于 BookKeeper 的多副本存储,即使 Broker 故障也能保障数据安全。天然支持多租户和隔离,可靠性和容错能力突出,尤其适合云原生环境。

总结

特性KafkaRabbitMQRocketMQPulsar
实现语言Java/ScalaErlangJavaJava
消费模式PullPushPullPull + Push
吞吐量极高一般较高较高
延迟极低,在高吞吐量情况下会受限
消息堆积能力极强(长期存储可回放)较弱强(分层存储,云原生)
扩展性极强,分区扩展一般,受限于集群和硬件资源较强极强,计算存储分离
可靠性极高,多副本高,Quorum Queue 提升可靠性较高,DLedger 提高主从切换容错极高,存储分离 + 多副本
协议支持Kafka 协议AMQP、MQTT、STOMP 等RocketMQ 原生及多协议扩展Pulsar 原生协议及多协议扩展
社区与生态活跃,生态最强稳定,插件丰富国内用户多,云支持好新兴但发展快,云原生场景活跃
适用场景日志采集、实时数仓、数据总线即时通信、任务调度、请求-应答电商订单、金融交易、支付系统SaaS 平台、跨数据中心消息流转

CloudCanal 如何支持数据流动?

上面我们对比了 Kafka、RabbitMQ、RocketMQ 和 Pulsar,可以看到它们在不同场景中各有优势。

无论选择哪一款消息中间件,都绕不开一个关键问题:如何把数据稳定、高效地同步到这些消息系统中?

这正是 CloudCanal 擅长的领域。CloudCanal 作为一款实时数据迁移与同步工具,具备以下特点:

  • 实时低延迟:基于 CDC 技术捕获数据库变更,秒级同步到各类主流消息中间件,保证数据的实时流动。
  • 一站式支持:同时支持 Kafka、RabbitMQ、RocketMQ、Pulsar 等主流消息系统,企业无需额外开发同步工具。
  • 自动化与可视化:提供友好的 UI 界面,支持任务配置、监控与运维全流程可视化,降低运维负担。
  • 部署灵活:支持本地私有部署和 SaaS 部署两种模式,适配不同规模的业务需求。

借助 CloudCanal,企业可以在不同消息系统之间自由选择和切换,而不必担心底层数据同步的复杂性。无论是构建实时数仓,还是支撑跨云多活的业务系统,CloudCanal 都能帮助开发者和 DBA 更快、更稳地落地。

如果感兴趣的话,欢迎跟着实操视频体验 五分钟完成 MySQL 到 Kafka 数据迁移同步

三步搞定!GaussDB 实时数据入仓

· 阅读需 5 分钟
John Li
John Li
Chief Executive Officer

随着信创的加速推进,GaussDB 等国产数据库已经进入越来越多的核心业务系统。但新的问题也随之而来:数据该怎么流动?

要做实时报表、风控模型、用户画像,甚至 AI 应用,数据需要从业务库流向分析型数据库或消息中间件。但是,稳定高效的同步工具并不好找。开源工具对国产数据库支持不足,自研方案成本高、维护复杂,很多企业都被卡住了。

有没有一种方式,既能保证稳定与安全,又能让 GaussDB 的数据实时流向下游?今天我们就要聊聊 GaussDB 数据实时入仓的解决方案。

GaussDB 数据入仓的技术难点

在实践中,要实现稳定高效的 GaussDB 数据同步,团队通常会遇到以下几大挑战:

  • 源库性能压力:传统触发器或轮询方式侵入性强,容易拖慢核心 OLTP 业务。
  • 一致性与延迟:需要保证数据不丢不重,同时延迟控制在秒级。
  • 异构适配难题:数据类型、事务模型、写入方式差异大,需要专业适配。
  • 全量+增量衔接:历史数据迁移和实时变更并行,数据容易出现重复或遗漏。
  • 运维复杂度高:自研或开源链路缺乏可视化监控,出错时排查和恢复困难。

如果没有成熟工具,企业往往需要自研管道(如基于 Kafka+Flink)来解决这些难点,不仅成本高,而且容易出现隐患。

CloudCanal 实时同步解决方案

针对 GaussDB 数据入仓中的五大挑战,CloudCanal 提供了完善的解决方案:

  • 高效的实时增量捕获

CloudCanal 基于逻辑复制槽(logical slot)实时捕获 GaussDB 增量数据,不依赖触发器或轮询查询,对源库性能影响极小,适合支撑核心 OLTP 业务的高并发场景。

  • 智能的数据映射与转换

内置丰富的数据处理能力,能够自动完成 GaussDB 与目标端的数据类型映射。同时,用户可以通过可视化的界面配置数据过滤、列裁剪、数据脱敏等,在同步过程中完成轻度的 ETL。

  • 强大的异构适配能力

内置 多种目标端支持,针对 MySQL、ClickHouse、Doris、SelectDB 等不同数据库,提供字段映射、批量写入优化、引擎级适配(如 ClickHouse MergeTree),降低了异构同步的门槛。

  • 全量+增量一体化迁移

CloudCanal 支持 并行全量导入 + 实时增量同步 的无缝衔接。迁移过程中可自动对齐数据快照与增量日志,保证数据不重不漏,真正实现业务不停机的平滑迁移。

  • 企业级的监控与告警

提供 可视化链路管理界面,支持实时监控延迟、RPS、CPU 使用率等指标,并内置自动告警与故障恢复能力,大幅降低运维复杂度。

使用场景

通过 CloudCanal 将 GaussDB 数据实时同步,可以支撑多样化的业务需求:

  • 实时数仓与决策分析:将数据同步至 Doris、ClickHouse 等,构建实时数仓,报表延迟从分钟级缩短到秒级,支持实时经营决策。
  • 用户画像与推荐引擎:互联网、零售、运营商等企业,需要对用户行为进行分析。将用户行为数据同步到 ClickHouse 或大数据平台,实时计算用户画像,驱动个性化推荐,提升转化率。
  • 混合云与多活架构:政企、能源等行业常有跨地域容灾或多云部署需求。将 GaussDB 数据实时同步至公有云数据库或异地灾备中心,实现多活架构,保证业务连续性和高可用。

操作演示

下面将以 GaussDB 到 Doris 的链路为例,展示如何五分钟实现数据实时同步。

前置准备

  1. 请参考 安装 SaaS 客户端,下载安装 CloudCanal SaaS 版。
  2. GaussDB 作为源端需要具备一定的权限,具体请参考 https://www.clougence.com/cc-doc/dataMigrationAndSync/datasource_func/GaussDB/privs_for_gaussdb

步骤 1: 添加数据源

登录 CloudCanal 平台,点击 数据源管理 > 添加数据源,分别添加 GaussDB 和 Doris 数据源。

步骤 2: 创建任务

  1. 点击 同步任务 > 创建任务
  2. 选择源和目标实例,并分别点击 测试连接

  1. 功能配置 页面,选择 增量同步,并勾选 全量初始化

  1. 表和操作过滤 页面,选择需要迁移同步的表,可同时选择多张。

  1. 数据处理 页面,保持默认配置。

  1. 创建确认 页面,点击 创建任务,开始运行。

CloudCanal 将自动完成 GaussDB 的结构迁移、全量数据迁移等工作,并实时捕捉并传输增量数据至 Doris。

总结

随着国产数据库的普及,数据的实时流动能力变得愈发重要。无论是构建实时数仓,还是支撑风控、画像、AI 应用,稳定的数据同步链路都是前提。CloudCanal 作为专业的数据迁移同步工具,能有效降低迁移复杂度,保障业务连续性,也让企业更快释放数据价值。

如果你正在寻找 GaussDB 数据同步方案,欢迎点击左下角 阅读原文,使用 CloudCanal SaaS 版快速上手,体验轻量、高效、稳定的数据同步新方式。

从达梦到 StarRocks:国产数据库实时入仓实践

· 阅读需 5 分钟
Zoe
Zoe
Docusaurus maintainer

随着国产化趋势的推进,达梦数据库在政务、金融、电信等关键行业中被越来越多地采用,处理着核心业务数据。与此同时,企业对数据分析的要求也在不断升级,传统报表已难以满足日益增长的实时分析诉求。构建实时高效、稳定可扩展的数据同步链路,已成为许多技术团队的迫切需求。

今天,我们将分享如何快速将达梦数据实时同步至新一代数仓(以 StarRocks 为例),打造面向国产化环境的实时数仓方案,实现从数据生产到分析决策的闭环。

架构设计

为了让达梦中的业务数据服务于实时分析,我们需要将其高效地同步至数仓 StarRocks。构建这条链路,其关键在于实时低延迟稳定易维护

CloudCanal 作为专业的端到端数据实时同步工具,具备低延迟高可靠的数据库变更捕获(CDC)能力,为达梦数据库到数仓(如 StarRocks)的迁移同步提供了一站式、自动化的解决方案

关键部分说明:

  • 全量初始化:CloudCanal 自动完成结构迁移和历史数据一次性迁移。
  • 增量采集:监听达梦数据库变更(Insert/Update/Delete)事件,支持 DDL 同步。
  • 实时转换:自动完成 数据格式标准化字段映射类型转换(如 DATE → DATETIME)。
  • 高速写入:通过 Stream Load 模式将数据写入 StarRocks 。

技术挑战与解决方案

增量实时同步

达梦数据库的增量同步能力主要依赖 LogMiner 机制,通过解析归档日志获取 DDL 与 DML 操作记录。然而,LogMiner 的使用过程复杂,且对日志完整性、会话资源等有较高要求,开发与运维门槛较高。

CloudCanal 的解决方案:

CloudCanal 原生集成了达梦的 DBMS_LOGMNR 机制,实现了对归档日志的自动解析和增量变更提取,用户无需手动编写调用逻辑。整个过程主要包括以下几个步骤:

  • 添加分析日志(ADD_LOGFILE
  • 解析日志(START_LOGMNR
  • 查询日志结果(V$LOGMNR_CONTENTS
  • 结束解析(END_LOGMNR

通过这一过程,实现了稳定、高效的达梦增量同步能力。

DDL 兼容问题

在解析达梦的 SQL DDL 时,常用的解析器(如 Druid)存在兼容性不足的问题,例如在 ALTER TABLE ... ADD COLUMN 等 DDL 语法上,Druid 无法正常解析,导致同步失败或中断。

CloudCanal 的解决方案:

CloudCanal 复用了 Oracle 解析器兼容达梦的 SQL,同时针对 DDL 不兼容的问题,提供了内置的关键字替换策略:用户只需开启一个可选参数,系统会在解析前自动将不兼容的语法进行转换(如 ADD COLUMNADD)。

这一设计有效解决了 DDL 同步中断的问题,提升了系统对达梦复杂 DDL 场景的适应能力,保障任务持续、稳定运行。

单一位点消费导致的性能瓶颈

传统同步架构中,增量同步往往采用单一消费位点,所有表的变更会按顺序串行处理。在某些场景下,这种模式会遇到性能瓶颈。例如,当一个同步任务包含 A、B、C 三张表,若 B 表在短时间内产生了数千万条海量变更,同步进程会因持续处理 B 表的数据而被长时间占用。这将导致 A 表和 C 表的增量数据被完全阻塞,出现严重的同步延迟。

CloudCanal 的解决方案:

CloudCanal 引入了表级别位点机制。该机制为每张表维护独立的消费位点,实现了不同表之间增量数据的并行拉取与消费,互不阻塞。这一机制显著提升了增量链路的吞吐能力与实时性。

实操演示

前置准备

  1. 请参考 全新安装(Docker Linux/MacOS),下载安装 CloudCanal 私有部署版本
  2. 达梦作为源端需要具备一定的权限,具体请参考 https://www.clougence.com/cc-doc/dataMigrationAndSync/datasource_func/Dameng/privs_for_dameng

步骤 1: 添加数据源

登录 CloudCanal 平台,点击 数据源管理 > 添加数据源,分别添加达梦和 StarRocks 数据源。

步骤 2: 创建任务

  1. 点击 同步任务 > 创建任务
  2. 选择源和目标实例,并分别点击 测试连接

  1. 功能配置 页面,选择 增量同步,并勾选 全量初始化

  1. 表和操作过滤 页面,选择需要迁移同步的表,可同时选择多张。

  1. 数据处理 页面,保持默认配置。

  1. 创建确认 页面,点击 创建任务,开始运行。

CloudCanal 将自动完成达梦的结构迁移、全量数据同步等工作,并实时捕捉并传输增量数据至 StarRocks。

总结

在国产化环境下,达梦与 StarRocks 之间的数据集成存在诸多挑战,特别是在实时性、兼容性与稳定性方面。CloudCanal 基于 CDC 技术,提供了面向达梦数据库的实时同步能力,支持表级位点、DDL 兼容性处理等关键能力,助力企业在国产化技术体系中构建稳定、可持续的实时分析平台。

CloudCanal + Apache Paimon + StarRocks 实时构建湖仓一体架构

· 阅读需 8 分钟
Barry
Chief Technology Officer

在实时数仓的浪潮下,企业越来越重视如何以低延迟、高一致性的方式将数据写入数据湖,并结合下游分析引擎完成统一分析。Apache Paimon 作为新一代流批一体的数据湖存储引擎,因其高效写入、实时更新等能力,成为构建实时湖仓架构的理想选型。

本文将介绍如何基于 Paimon、CloudCanal、StarRocks 快速构建一套真正实时、灵活、高可维护的数据湖仓架构。

Apache Paimon 介绍

Apache Paimon 是一个开源的、面向流计算的湖仓存储格式,源于 Apache Flink 社区(原 Flink Table Store)。它的核心创新在于将 湖存储格式日志结构合并树(LSM-tree) 技术融合,为数据湖带来了强大的实时流式更新能力,这使得高吞吐、低延迟的数据摄取、变更日志追踪和高效的即时分析成为可能。

核心能力:

  • 流批一体处理:支持 Streaming Write / Snapshot Read
  • 主键支持:高效 UPSERT / DELETE
  • Schema 演进:新增、删除、修改列,无需重写旧数据
  • ACID 事务保障:支持并发读写一致性
  • 生态兼容:支持 StarRocks、Flink、Spark 等引擎
  • 对象存储兼容:支持 S3OSS 等文件系统

举个例子:数据湖中的实时订单状态变更

以大型电商平台的实时销售大屏为例,业务团队希望能够每秒更新订单状态,例如订单从“已支付”变为“已发货”,并立即体现在可视化大屏中。

  • 传统方案的挑战(Merge-on-Read)

在传统的数据湖架构中,变更数据通常会先追加写入日志区,再依赖定期的 Merge-on-Read 批处理任务将新旧数据合并成最新快照。

  • 实时写入采用 追加方式,变更记录不会立即反映在查询结果中,需等待合并操作完成后才可见。
  • 读旧、写新、重写文件的过程通常以分钟为单位,难以满足秒级迟需求。
  • Paimon 的解决方式(LSM-tree)

Paimon 从架构层面对这一痛点进行了优化,引入类似数据库的主键更新能力。

  • 订单在交易库(如 MySQL)中状态变更。
  • 变更事件(如 UPDATE orders SET status = '已发货' WHERE order_id = '123')实时写入 Paimon。
  • Paimon 基于 LSM-tree,更新后读取,通常可在 秒级 内完成。
  • 实际效果

下游如 StarRocks 等分析引擎可以秒级查询到更新后的状态,从而确保实时大屏始终反映业务的最新动态。

Paimon vs. Iceberg:关键特性对比

Apache Paimon 与 Apache Iceberg 是当前数据湖领域的两大主流方案,分别在实时处理和批量分析方向各有侧重,体现了两种不同的技术演进路径。

Paimon 设计之初就面向流式数据处理,底层采用 LSM-tree 架构,原生支持主键和高效变更,特别适合 高频更新CDC等行级数据实时入湖场景。

Iceberg 以快照机制为核心,强调 强一致性,同时也逐步增强对流式写入与变更处理的支持,具备实现近实时入湖的能力。

特性Apache PaimonApache Iceberg
核心更新机制LSM-treeCopy-on-Write / Merge-on-Read
主键与更新模型支持 Primary Key,流式 UPSERT 写入更高效通过 Merge-on-Read 机制支持 UPSERT
流式写入支持支持
数据更新延迟毫秒到秒级,更适合实时性要求极高的场景通常为分钟级,更侧重于批处理和微批处理
生态成熟度较新,在 Flink 社区中发展迅速更成熟,拥有更广泛的引擎和工具支持
适用场景实时数仓、CDC 数据实时入湖、流批一体分析通用数据湖、大规模批处理、数据仓库

总体来看,Paimon 在实时更新、变更频繁的场景中具备更直接的能力优势,而 Iceberg 则在批量处理、版本治理和生态成熟度方面表现更稳健

构建湖仓一体架构

尽管 Paimon 可以通过 Flink CDC 写入数据,但管理作业状态、处理容错和检查点等工作,对多数团队而言仍有不小的技术门槛和运维成本。CloudCanal 提供了一种更轻量、更自动化的方式实现数据入湖。

  • 外部数据源:企业的核心交易库(如 MySQL, PostgreSQL)、日志数据(Kafka)等。
  • CloudCanal
    • 基于日志实时捕获数据的变更,流式批量写入,实现秒级延迟。
    • 支持 **结构自动迁移 **和 DDL 同步。
    • 支持数据迁移同步、数据校验与订正、断点续传、任务监控、告警。
  • Apache Paimon
    • 作为湖仓底座,承接 CloudCanal 写入的实时数据流。
    • 采用 LSM-tree 架构自动去重合并,管理数据分区与后台 Compaction
    • 基于 **S3、OSS **等其他对象存储,构建存算分离架构。
  • StarRocks:直接进行实时查询分析,无需额外的数据导入或转换。

实操演示

接下来将以 MySQL -> Paimon 链路为例,展示如何快速将数据实时同步至 Paimon,并使用 StarRocks 外表实时查询入湖数据。

步骤 1: 安装 CloudCanal

请参考 全新安装(Docker Linux/MacOS),下载安装 CloudCanal 私有部署版本

步骤 2: 添加数据源

  1. 登录 CloudCanal 平台,点击 数据源管理 > 添加数据源,分别添加 MySQL 和 Paimon 数据源。

  1. 添加 Paimon 数据源时,需配置额外参数,具体可参考:Paimon 数据源配置

步骤 3: 创建任务

  1. 点击 同步任务 > 创建任务
  2. 选择源和目标实例,并分别点击 测试连接

  1. 功能配置 页面,选择 增量同步,并勾选 全量初始化

  1. 表和操作过滤 页面,选择需要迁移同步的表,可同时选择多张。

  1. 数据处理 页面,保持默认配置。

6. 在 创建确认 页面,点击 创建任务,开始运行。

任务启动后,CloudCanal 会自动完成全量数据的初始化,并实时捕获增量变更写入 Paimon。

步骤 4: 使用 StarRocks 查询数据

Paimon 中的数据最终需要被下游分析引擎查询,StarRocks 原生支持 Paimon Catalog,可通过外部 Catalog 的方式直接查询 Paimon 中的实时数据,无需额外导入或数据转换。

  1. 在 StarRocks 中创建 Paimon Catalog

在 StarRocks 中执行 CREATE EXTERNAL CATALOG 语句,即可将整个 Paimon 仓库映射进 StarRocks:

CREATE EXTERNAL CATALOG paimon_catalog
PROPERTIES
(
"type" = "paimon",
"paimon.catalog.type" = "filesystem",
"paimon.catalog.warehouse" = "<s3_paimon_warehouse_path>",
"aws.s3.use_instance_profile" = "true",
"aws.s3.endpoint" = "<s3_endpoint>"
);

具体配置可参考:https://docs.starrocks.io/docs/data_source/catalog/paimon_catalog/#examples

  1. 实时查询数据

Catalog 创建成功后,可以像 操作本地表 一样查询 Paimon 中的数据:

-- 查看 Catalog 中有哪些数据库
SHOW DATABASES FROM paimon_catalog;

-- 切换 Catalog
SET CATALOG paimon_catalog;

-- 切换至指定数据库
USE your_database;

-- 查询表数据
SELECT COUNT(*) FROM your_table LIMIT 10;

当 MySQL 中的数据发生变化后,CloudCanal 会将变更实时同步至 Paimon,StarRocks 查询到的数据也将同步更新,从而实现真正的端到端 秒级实时分析能力,无需构建复杂的 ETL 流程。

总结

Apache Paimon 以其创新的 实时更新 能力,为现代数据湖仓架构注入了新的活力,而 CloudCanal + Paimon 的组合,则通过零代码、自动化的方式,快速落地高性能的实时湖仓,最后与 StarRocks 等下游引擎配合,打通了从数据同步到实时查询的完整闭环。

大规模数据迁移太慢了?试试这几种方法

· 阅读需 7 分钟
Zoe
Zoe
Docusaurus maintainer

很多开发人员在迁移大规模数据时,常常会碰到一个让人头疼的问题:速度慢,尤其当数据量上升到 TB 级别、业务系统不能停机的场景下,传统的串行迁移方案几乎难以满足时间和稳定性要求。

这篇文章就来聊聊大规模数据迁移为什么慢,以及几种常用的提速方法。最后,我们也会简单提到 CloudCanal 在这方面提供的一个能力:任务组,帮助你更高效、更有序地执行多任务迁移。

为什么大规模数据迁移这么慢?

大规模数据迁移之所以慢,往往不是单一因素造成的,而是多个因素交织的结果。

  1. 网络瓶颈
    从 IDC 到公有云,或跨区域迁移时,网络带宽和延迟直接决定了传输速度。带宽不足会导致数据传输缓慢,而高延迟则会增加每次数据包往返的时间。

  2. 源端/目标端性能限制

    • 数据在迁移过程中通常需要进行处理,如数据转换、压缩、解压缩等,这些操作会消耗大量的 CPU 和内存资源。如果资源不足,任务就会排队等待,导致整体速度下降。
    • 数据库本身的配置,如缓冲区大小、并发连接数、日志模式等,都会影响数据读写效率。不合理的配置会限制迁移工具的性能发挥。
  3. 数据特性与复杂性

    • 对于没有主键或索引的大表,全表扫描效率低,数据分片和并行处理较为困难,极易出现性能瓶颈。
    • BLOB、CLOB 等大对象数据类型,以及包含大量嵌套结构的数据,处理起来比简单数据类型更耗时。
  4. 工具与策略选择不当
    并非所有迁移工具都适用于所有场景。选择不适合大规模数据的工具(如 mysqldump 默认是串行导出导入),或者没有合理的迁移策略,都可能事倍功半。

如何提速?

下面是几种在实践中常用的大规模数据迁移提速策略:

  1. 并行处理与并发优化

    • 任务拆分:将一个庞大的迁移任务分解为多个独立的小任务,例如按表并行、按数据范围并行(如通过主键范围、哈希分片),然后同时执行这些任务。
    • 增加并发连接数:调整迁移工具、数据库和操作系统的并发连接数限制,允许更多的连接同时读写数据。注意并发数不是越高越好,应评估目标库并发承压能力。
    • 多线程:在迁移工具层面,启用多线程模式,并行处理数据。
  2. 优化网络与传输

    • 提升网络带宽:升级网络设备,增加源端和目标端之间的网络带宽。对于跨云或跨地域迁移,考虑使用专线或高速通道。
    • 减少网络延迟:尽可能缩短源端和目标端之间的物理距离。
    • 数据压缩:在网络带宽有限但 CPU 资源充足的情况下,可以考虑采用 GZIP/LZ4 压缩数据,节省带宽。但这需要权衡压缩和解压缩带来的 CPU 开销。
  3. 提升源端与目标端性能

    • 硬件升级:升级更快的 CPU、增加内存可以显著提升数据处理能力。
    • 数据库优化:调整数据库缓冲区、日志文件大小、并发连接数等参数,以适应高并发写入。同时将批量插入替代逐条写入,批次大小根据目标库写入能力动态调整。
  4. 优化数据处理策略

    • 数据分片策略:针对大表,选择合适的分片策略。对于无主键表,可以考虑使用 rowid(如果数据库支持)或其他自定义方式进行逻辑分片。
    • 增量+全量结合:对于需要保持业务连续性的场景,可以先进行全量迁移,然后通过增量同步工具(如 CDC 工具)捕获并同步全量迁移期间产生的增量数据,最后进行业务切换,最大限度地减少停机时间。
    • 跳过不必要的数据:提前识别并过滤掉不需要迁移的数据,减少迁移总量。
  5. 选择合适的工具与平台
    根据数据量、业务复杂度、数据安全需求等综合评估,可选择官方迁移工具、第三方迁移工具或自研工具,关于如何选型,可参考 数据库官方工具与第三方工具如何选择?

CloudCanal 任务组:数据并行迁移同步

在解决大规模数据迁移慢的问题上,数据迁移同步工具 CloudCanal 提供了一个非常实用的能力:任务组,帮助开发人员有组织、有节奏地管理多个并发数据流:

  1. 自动拆分任务
    当任务加入并行组时,系统会自动为其分配一个序号。任务运行时,系统会基于 Hash(主键) mod 并行度 == 当前任务序号 的条件自动进行数据过滤。

  2. 并行迁移
    任务组内各任务并行执行,仅消费各自所属部分的数据,提升迁移同步性能。个别任务失败不会影响整个组,便于局部重试。

  3. 统一监控与追踪
    任务组作为一个逻辑单元,迁移过程更透明、状态更清晰,方便统一展示、统一控制。

为验证并行任务组对数据迁移性能的提升,我们进行了一次性能对比测试,数据链路为 MySQL -> MySQL,具体结果如下:

任务类型单任务运行4 个任务并行
任务规格4GB4GB
待消费数据 (条)1000w1000w
完成时间 (估计值 秒)330 s180 s200 s195 s230 s
RPS (最大)43.00 k15.52 k13.99 k14.34 k14.52 k
RPS (平均)40.70 k14.49 k13.21 k13.49 k14.20 k

由上表可见,全量任务下 4 个任务并行,约能够带来 30 % 的性能提升。但由于并行任务下每批量能够拉取的数据减少,性能提升并非线性。

总结

大规模数据迁移慢并非无解,关键在于科学规划、合理分片、并行处理和工具选型。如果你正在面对大体量的数据迁移场景,不妨试试用更系统化、自动化的方式来组织你的任务流,比如通过 CloudCanal 的任务组能力,更高效地完成数据迁移任务,同时确保数据的一致性和系统的稳定性。

深入浅出数据库宽表

· 阅读需 9 分钟
Barry
Chief Technology Officer

在企业级数据场景中,一个报表查询往往需要 3 张以上表的 JOIN,这类查询在数据量较大的场景下,需要数分钟甚至个把小时才能返回。

本文将简要探讨宽表技术的来龙去脉,以及它如何帮助解决多表关联带来的性能瓶颈,并结合 CloudCanal 最新推出的可视化宽表构建功能,无痛实现跨表数据的实时整合。

数据分析困境

在结构化数据系统中,随着业务模型的复杂化,数据表之间的关联不断增多。以电商系统为例,订单、商品、用户等表结构天然具有关联性:

  • 订单数据:商品 ID (关联 商品数据)、数量、总价、优惠信息、买家 ID (关联 用户数据)等
  • 商品数据:名称、颜色、质地、库存、商家 ID (关联 用户数据)等
  • 用户数据:账号、密码、昵称、手机、邮箱等

关系型数据库通过建立关系范式实现了存储效率最大化(冗余信息少),并优化了事务型操作的性能。但一旦进入数据分析阶段,这种表结构会给查询带来极大挑战。

在进行批量聚合、筛选等复杂分析时,如“计算过去 1 个月商品销售额 Top 10”,往往需要多表 JOIN 操作。而随着关联表数量增加,可能的执行计划(搜索空间)也呈几何级增长:

关联表数量排列种类
22
424
6720
840320
103628800

对于一个 ERP 或 CRM 系统而言,5 张表以上的关联是常态。面对如此庞大的执行计划可能性,如何高效地找到最优解 成为数据库分析查询的核心难题。

面对这一挑战,行业演进出了两种技术路线:查询优化预计算。而 打宽表 是预计算的核心能力之一。

查询优化 vs 预计算

查询优化

面对这么多种可能性,解决方式之一就是通过减少可能性加快搜索,这就是数据库优化器术语——剪枝。其中衍生出两种技术:基于规则的优化器(RBO: Rule-Based Optimizer)基于代价的优化器(CBO: Cost-Based Optimizer)

  • 基于规则的优化器(RBO):RBO不考虑数据实际分布,而是依据预设的静态规则对 SQL 执行计划进行调整。市面上的数据库产品,都有一些通用的优化规则,如谓词下推等。不同数据库产品基于其业务属性和架构特点,还拥有独特的优化规则,如 SAP Hana 承载 SAP ERP 业务,针对全内存和大量 JOIN 的场景,其优化器规则便与其他数据库存在显著差异。

  • 基于代价的优化器(CBO):相较于 RBO,CBO 通过评估不同执行计划的 I/O、CPU 等资源消耗,选择代价最低的计划。这种优化方式会通过数据的具体分布与查询 SQL 的特点来动态调整,即使两条一模一样的 SQL,因为设置的参数值不一样,可能最后的执行计划大相径庭。CBO 一般具备一个精密复杂的统计信息子系统,包括各个表的数据量、基于主键或者关联维度的数据分布直方图等信息。

现代数据库内核一般会联合使用 RBO 和 CBO 对 SQL 进行优化。

预计算

预计算认为 关联表之间的数据关系是确定的,所以在数据生成时就进行聚合与关联,形成一张“宽”的表结构,从而避免后续每次查询都重新进行关联。数据发生变化时,仅需增量更新对应的宽表数据。它的早期实现可以追溯到关系型数据库的 物化视图

从计算量消耗角度而言,预计算大幅优于即时查询优化。然而,其局限性亦不容忽视:

  • JOIN 语义实现受限:预计算对于非 Left Join 语义的实现逻辑复杂且代价巨大,通常难以在流式处理中高效支持。
  • 大量数据更新影响稳定性:在 1 对 N 的数据关系中,若“1”端数据发生变化,可能导致宽表数据大规模更新,对服务稳定性构成挑战。
  • 功能与性能权衡:预计算通常无法像即时查询那样支持各种聚合、过滤条件及函数,部分是功能实现难度,部分是性能代价考量。

最佳实践

在真实场景中,业界普遍倾向于 “双管齐下” 的策略:预计算生成中间数据,而即时查询则在此基础上完成最终的聚合与过滤,实现功能与性能的平衡。

  • 预计算:当前最流行的方案即 流计算,近些年出现的流式数据库也在尝试更好地解决这类问题,传统关系型数据库或者数据仓库实现的物化视图也是一种很好的解决方案。

  • 即时查询:随着 列式行列混合 数据结构普及,AVX 512 等新指令集落地,FPGA、GPU 等专用或高性能计算硬件尝试,以及 知识网格分布式计算 等软件手段应用,实时分析数据库在数据筛选和聚合性能上获得了显著提升。

两者结合使用,为在线数据分析场景带来了巨大的助益。

CloudCanal 的宽表历程

CloudCanal 在宽表构建方面的演进,实现了从“高代码门槛”到“零代码构建”的转变。早期版本中通过自定义代码支持用户在数据迁移同步过程中,自行查询关联表数据并构建宽表,再回写到目标端。尽管功能可行,但用户需要写代码,难度太高,因而未形成大规模应用。

为此,CloudCanal 实现了 可视化宽表构建。用户仅需在界面中选择需要打宽表的表,并选择关联的列,即可构建出一个既支持历史数据迁移,又支持实时更新的宽表任务。

目前,该功能已支持链路包括:

  • MySQL -> MySQL/StarRocks/Doris/SelectDB
  • PostgreSQL/SQL Server/Oracle/MySQL -> MySQL
  • PostgreSQL -> StarRocks/Doris/SelectDB

未来将持续开放更多链路。

CloudCanal 可视化构建宽表

宽表定义

CloudCanal 宽表构建中的核心角色包括:

  • 驱动表:仅可选择一张,作为宽表的基准数据源。
  • 关联表:可选择多张,提供驱动表需要补充的字段信息。

CloudCanal 默认实现 Left Join 语义,确保返回驱动表所有数据,即使关联表中无匹配数据。

目前,CloudCanal 支持 2 种关联拓扑结构:

  • 线形 关系:A.b_id = B.id and B.c_id = C.id and ...,其中所有表均不可重复选择,且不支持形成环状关联。
  • 星形 关系:A.b_id = B.id and A.c_id = C.id and ...,不支持形成环状关联。

其中 A 表定义为驱动表,B、C 表定义为关联表。

数据变更处理策略

对端为关系型数据库(如 MySQL)

  • 驱动表 INSERT:自动补全关联表字段。
  • 驱动表 UPDATE/DELETE:不做关联表字段关联。
  • 关联表 INSERT:如有下一层关联表,则做关联表字段关联,INSERT 操作转换为 UPDATE。
  • 关联表 UPDATE:如有下一层关联表,不做关联表字段关联。
  • 关联表 DELETE:如有下一层关联表,则做关联表字段关联,DELETE 操作转换为全字段为 NULL 的 UPDATE 操作。

对端为整行覆盖类数据库(如 StarRocks/Doris)

  • 驱动表 INSERT/UPDATE/DELETE:自动补全关联表字段。

  • 关联表 INSERT/UPDATE/DELETE:自动忽略。

    信息

    若需实现到覆盖类数据库 关联表变更,可以分阶段完成。

    首先创建 源库 > 关系型数据库宽表 迁移同步任务,再创建 关系型数据库宽表 > 覆盖类数据库 迁移同步任务。

操作示例

  1. 进入 CloudCanal 控制台,点击 同步任务 > 创建任务
  2. 进入 选择表 步骤,选择需要打宽表的表,对端均选择宽表进行映射。
  3. 进入 数据处理 步骤。
    1. 页面左侧选择 驱动表,并点击 操作 > 宽表,设定宽表定义。

      • 关联列 选择和设置,支持多个。

      • 关联表 其他列 选择,以及宽表映射字段填写,此操作主要防止多张来源表字段名在目标宽表中重复。

        信息

        1. 关联表如果级联关联其他表,务必选择其对应关联列。如 A.b_id = B.id and B.c_id = C.id,则选择 B 的其他列时,必须选择 c_id。

        2. 在复杂关联关系中,不同驱动表或关联表存在相同列名,故在选择其他列时,映射到不同列以规避冲突

    2. 点击 确定 完成设置。

    3. 页面左侧选择 关联表,确认列和宽表列映射正确。

  4. 继续完成任务创建流程,即可启动宽表同步任务。

总结

宽表作为一种核心的数据预计算策略,有效解决了关系数据库范式化设计在 OLAP 场景下多表关联查询的性能瓶颈。CloudCanal 提供的可视化宽表构建能力,不仅大幅简化了构建流程,而且显著降低了技术门槛。它为构建具备实时性与灵活性的数据分析平台提供了关键工具,助力数据架构师和 DBA 高效构建实时数据分析层。

Redis 数据迁移同步优化(二):应对大 Key 同步挑战

· 阅读需 4 分钟
John Li
John Li
Chief Executive Officer

在企业级的数据同步和迁移场景中,Redis 凭借高性能和灵活的数据结构,常被用于缓存和高频读写场景。随着业务数据的积累,Redis 中不可避免会出现包含大量元素的“大 Key”,如包含几十万条数据的 List、Set 或 Hash 类型。在进行全量同步或迁移时,大 Key 往往成为性能瓶颈甚至故障源。

CloudCanal 作为专业的数据迁移同步工具,不断优化 Redis 同步技术,近期对 Redis 源端链路又完成了一系列优化,包括更多指令支持数据校验以及 全量大 Key 同步优化。本文重点介绍在大 Key 同步场景下,CloudCanal 的技术优化与性能提升。

大 Key 同步挑战

在高并发、高实时性的业务系统中,Redis 某个 Key 的元素可能高达数十万甚至上百万。一旦执行全量数据同步,容易带来如下问题:

  • 内存占用剧增(OOM):一次性加载整个大 Key 会使任务程序的内存瞬时暴涨,严重时可能引发 OOM。
  • 协议限制超限:Redis 协议对单条命令的参数数量和请求体大小有上限(如 RESP 协议中为 512MB),超出即报错。
  • 对端写入失败:Redis 目标节点在处理过大命令时,可能因资源不足而拒绝执行,导致同步中断。

CloudCanal 同步技术优化

为解决上述问题,CloudCanal 引入了针对大 Key 的延迟加载与分片同步机制,确保在不牺牲一致性前提下,顺利完成 Redis 全量同步。

延迟加载

传统同步方式往往一次性读取整个 Key 内容加载到内存中,CloudCanal 则采取延迟加载策略,即在全量同步过程中,源端 Redis 的数据不会立即加载到内存中,而是通过 分片 的方式逐步加载和处理。这种方式可以 有效减少内存占用,避免程序 OOM 问题。

大 Key 分片同步

CloudCanal 对 Redis 源端链路的核心优化是将大 Key 拆分成多个“小片段”,分片写入目标 Redis。每个片段包含的元素数量可以通过参数灵活控制:

  • 参数名:parseFullEventBatchSize
  • 默认值:1024
  • 类型支持:List、Set、ZSet、Hash

例如,一个包含 50 万元素的 Set,可以被拆成约 490 个片段,每次发送一个 SADD 命令携带 1024 个元素。

分片同步流程

  1. 分片计算:CloudCanal 首先统计大 Key 中的元素总数,并根据设定的参数 parseFullEventBatchSize 将其切分成多个片段。
  2. 片段构造与发送:每个片段被构造成符合 Redis 协议限制的命令,多次发送,最终重建完整 Key 内容。
  3. 顺序与原子性保证:每个片段按顺序写入,确保目标端数据一致性。

实际效果

CloudCanal 测试了优化后的大 Key 同步效果,数据准备如下:

  • 100w 普通大小 Key(包含:String、Set、ZSet、List、Hash)
  • 5w 30 MB 大小 Key(包含:String、Set、ZSet、List、Hash,最大 Key 35 MB左右)

数据同步性能如下:

结果显示,CloudCanal 在 Redis 到 Redis 数据同步(包含大 Key 场景)中,基准 RPS 可达到 4-5 K 左右,基本能够满足业务日常同步需求,并确保数据准确。

总结

通过延迟加载与分片同步机制,CloudCanal 有效避免全量同步过程中可能出现的 OOM 问题和协议限制问题,从而提升全量同步的稳定性和可靠性。

数据实时同步典型问答(一)

· 阅读需 6 分钟
Zoe
Zoe
Docusaurus maintainer

简介

在数据实时同步领域深耕多年,我们常常会被问到或者遇到一些重复的问题,有些回答随着我们经历的业务场景增多有所变化,但大部分都经得起推敲。我们将整理常见问题,并持续分享。

本期问题目录

  • 数据库官方工具与第三方工具如何选择?
  • 业务能依赖实时同步工具的延迟吗?
  • 数据库实时同步工具为业务带来的真正价值是什么?
  • 同步工具能保持长期稳定和不丢数据吗?

数据库官方工具与第三方工具如何选择?

一般成熟的数据库厂商会自带数据迁移、冷/热备份工具,甚至有一些厂商会提供完整的数据同步解决方案。

经过大量实践验证,我们总结出以下关键点:

官方工具优势

  • 相对来说具备最好的迁移同步性能。
  • 能规避数据库自身的特定缺陷。
  • 支持第三方工具难以实现的特殊场景(如 Oracle GoldenGate 解析 Redo 日志)。

官方工具局限

  • 对其他数据库支持有限或缺失。
  • 面向通用场景,特殊需求支持不足。
  • User Lock-in 倾向,数据进出难度不对等。

选型建议:

推荐按照场景来选择:

  • 涉及数据库本身运维的场景,如冷/热备份、同构迁移同步,推荐用官方工具
  • 涉及异构数据迁移同步的场景,如关系型数据库到数据仓库/消息中间件/缓存/搜索引擎等,推荐用第三方工具
  • 涉及特殊场景,如对数据进行过滤、计算,推荐用第三方工具
  • 官方工具不支持但第三方工具支持的场景,推荐用第三方工具

业务能依赖实时同步工具的延迟么?

简单来说,非分布式事务保障的数据同步,都有延迟的风险。而分布式事务也不是没有代价,一般通过复制冗余和牺牲业务写入延迟(或中断)确保一致性。

数据同步的延迟分为 故障性延迟业务性延迟,以下通过例子简要进行说明。

故障性延迟

  • 同步工具自身问题,包括内存紧张、逻辑 bug 等。
  • 源端或者对端数据库故障,前者拉不到数据,后者写入不了数据或者写入慢。
  • 对端数据存在约束冲突,写入报错。
  • 对端数据结构不完整,写入报错。

业务性延迟

  • 源端数据库导入数据或订正数据,导致流量增大。
  • 业务高峰流量超出同步工具处理能力。

虽然通过 任务调优数据库资源规划数据库变更规范 等措施可以降低延迟概率,但完全杜绝延迟并不现实。

业务能否依赖同步延迟,关键在于上述情况发生时,能否通过应急预案(如 业务主动降级)等方式进行规避。

数据库实时同步工具为业务带来的真正价值是什么?

数据库实时同步工具第一价值是 增量,也就是新产生的变更能够复制到对端执行。相比传统 ETL ,有三大优势:

  • 实时性:增量是实时前提,实时是满足风控等特定场景的必要条件。
  • 高效性:增量仅同步变更数据,大幅节省带宽。如 10 亿数据一天变更 100 条,增量只需同步这 100 条变更数据,无需扫描整个数据集,更不需要重新搬迁 10 亿数据。
  • 完整性:增量可同步删除、结构变更操作,而 ETL 往往需要元数据服务进行辅助。

数据库实时同步工具第二价值是 实时。在源端数据源上新产生的数据,可以亚秒级或者秒级到目标数据源。

业务系统的数据库往往分工明确,这既是因为当前数据库技术存在局限,也因为业务对数据有多样的需求。同步工具通过实时同步弥合了这个需求和能力的差异,典型场景如既要保证事务读写,又要对数据做复杂检索分析。

同步工具能保持长期稳定和不丢数据么?

同步工具的不稳定大部分是因为 数据结构变更业务流量变化数据库网络环境 三因素引起,控制或规划这些风险因素能够最大限度降低不稳定的发生概率。

数据结构变更 包括:

  • 变更方式和同步任务能力或配置不匹配,如原生数据库 DDL、pt-osc、gh-ost 等 Online DDL 工具。
  • 变更语法范围较大,同步工具可能支持不全,导致 DDL 变更错误或源表和目标表结构不一致。
  • 下游数据源结构改动或数据写入,未顾及同步任务,导致写入数据和目标结构不匹配或约束冲突。

业务流量变化 包括:

  • 业务造成突发峰值流量,同步任务未为此调优性能,导致内存紧张,同步不正常。
  • 数据库数据运维造成流量激增,如大范围数据订正,同步任务未为此调优性能,导致内存紧张,同步不正常。

数据库网络环境 包括:

  • 数据库白名单未加入同步节点,任务调度到此类节点后无法连接数据库。
  • 跨地域网络延迟较高,导致数据读取或写入困难。

这些风险点,通常可以通过 数据库变更规范任务峰值流量演练资源上线检查 等措施大幅度缓解。

数据丢失的问题,从我们的经验来看,主要是由于 并行策略不匹配 导致乱序、对端数据写入 导致数据冲突、延迟过大没有及时处理 导致源端增量日志被删除。

  • 并行策略不匹配 场景较偏,一般是由唯一键字段值级联更新或重用造成。需要在同步工具中降级为更大粒度(比如表级)进行同步,不过往往事后发现,需要辅助用校验订正做处理。
  • 对端数据写入 导致同步工具写入数据冲突,一般通过回收业务账号写入权限,规范对端数据库使用方式进行解决。
  • 延迟过大没有及时处理 则需要在同步工具中设置并验证告警,并且加长源端数据库保留日志的时间,一般建议大于等于24小时。

通过以上措施,可大幅提升同步系统的稳定性和数据可靠性,为业务提供坚实的数据基础保障。

跨洲际数据迁移同步最佳实践

· 阅读需 6 分钟
Zoe
Zoe
Docusaurus maintainer

背景介绍

在 CloudCanal 长期支持企业业务数据迁移同步的过程中,跨省、跨国,乃至跨洲的业务数据迁移同步是常见的需求之一,许多客户经常问到:如何部署 CloudCanal 以及做任务调优比较好?

对于这个问题,我们从自身产品技术角度能够提供一些建议,但实际情况往往复杂得多,这也是本文要讨论的问题。本文将基于理论与实践,深入探讨跨洲际数据迁移同步的最佳实践方案。

跨洲际数据迁移同步的挑战

跨洲际数据迁移同步面临的主要挑战来自两个方面:

  • 不可避免的网络延迟:例如新加坡到美国的网络延迟通常在 150 ms~300 ms之间,相比关系型数据库单条按主键 INSERT/UPDATE 操作(通常小于 5 ms)高出两个数量级。
  • 复杂的网络质量因素:包括丢包率、网关路径和处理时间等问题。与内网传输相比,跨洲际传输需要经过机架、机房、骨干网上的多层交换机和路由器等设备。

另外针对数据库迁移同步,还需要考虑源、对端数据库的忙碌程度、网络带宽和数据传输量的匹配关系等。

如果使用 CloudCanal,则需要了解其源端数据获取和目标端数据写入机制,以初步确定部署方案。

CloudCanal 迁移同步的优化

数据迁移技术

对于关系型数据库的数据迁移,CloudCanal 使用 JDBC 逻辑扫描数据,并且在表结构支持的情况下,通过分页等方式做到断点续传,另外支持自动表间并行,以及通过手动设定过滤条件实现表内并行(需多个任务)。

在数据迁移的目标端,因为所有来源数据均为 INSERT,且数据天然按表成批,所以固定优化写入方式包括:攒批拆分并行batch 写入INSERT 重写(相同表多条数据转换成 insert..values(),(),())。

数据同步技术

CloudCanal 数据同步过程中,获取增量数据的方式因源端数据库不同有所差别,如下表所示:

源端数据库类型增量获取方式
MySQLBinlog 解析
PostgreSQLlogical wal 订阅
OracleLogminer 解析
SQL ServerSQL Server CDC 表扫描
MongoDBoplog 扫描 / ChangeStream 服务
RedisPSYNC 指令
SAP HanaTrigger
Kafka消息订阅
StarRocks周期性增量数据扫描
......

除了部分主动扫描技术,大部分都依赖数据库"吐"增量数据的效率,具有一定的不可控性。

数据同步的目标端,和数据迁移的区别在于 操作种类更多(INSERT/UPDATE/DELETE),且需要保证数据顺序一致性,故优化方式也有所区别。

优化方式说明
攒批减少网络交互、实现部分目标端数据库高效合并
按数据唯一标识分区并行满足基本的数据保序要求
按表级别分区并行对于数据唯一标识变更的弱化并行方式
多语句关系型数据库普遍可以通过分号拼接操作优化网络传输
bulk load对于具备全镜像,且目标端具备 upsert 能力的来源数据,将 INSERT/UPDATE 转换成 INSERT 批量写入并覆盖
分布式任务创建多个任务对相同来源数据进行分区后写入

跨洲际同步最佳实践探索

从 CloudCanal 技术实现来看,目标端写入优化措施比源端更多且更可控。因此,我们通常建议将 CloudCanal 与源端数据库部署在同一区域,以降低网络延迟、网络质量等因素对数据获取的影响。

但这一理论假设是否成立?我们通过 MySQL 到 MySQL 的跨洲际迁移同步进行了实际验证。

前置准备

资源准备:

  • 源端 MySQL:新加坡机房(4 核 8GB 内存)
  • 目标端 MySQL:美国硅谷机房(4 核 8GB 内存)
  • 部署 CloudCanal:分别在新加坡和硅谷各准备一台虚拟机(Linux x64,8 核 16GB 内存)用于部署 CloudCanal

实验计划:进行两次相同的数据迁移和同步,对比数据迁移和数据同步的性能。

实验过程

  1. 新加坡 MySQL 上新造 130 万行数据。
  2. 使用部署在 新加坡虚拟机上的 CloudCanal 任务迁移 新加坡 MySQL 数据到 硅谷 MySQL,记录新加坡迁移任务的性能。
  3. 新加坡 MySQL 上变更一批数据(UPDATE 和 INSERT),记录新加坡同步任务的性能。
  4. 停止新加坡迁移同步任务,删除 硅谷 MySQL 上的数据。
  5. 使用部署在 硅谷虚拟机上的 CloudCanal 任务迁移 新加坡 MySQL 数据到 硅谷 MySQL,记录硅谷迁移任务的性能。
  6. 新加坡 MySQL 上变更一批数据(UPDATE 和 INSERT),记录硅谷同步任务的性能。

实验结果与分析

任务位置类型性能
新加坡数据迁移6.5k records/sec
硅谷数据迁移15k records/sec
新加坡数据同步8k records/sec
硅谷数据同步32k records/sec

从实际操作结果来看,将 CloudCanal 部署在目标端(硅谷)环境时,数据迁移同步性能显著优于部署在源端(新加坡)的方案,这与我们的初始假设相悖。

经过深入分析,可能的原因包括:

  • 两地机房网关安全策略、上下行带宽存在差异。
  • CloudCanal 批量写入因网络质量等因素影响,效率反而没有 binlog 传输或逻辑扫描效率高。
  • 其他未知因素。

最佳实践

上述的验证,对跨洲际数据迁移同步有一定的参考意义,但可能和实际业务情况存在一定的差距,如:

  • 业务数据库负载较重,实际应用中源端可能无法充分推送增量数据。
  • 业务有不同质量的专线,网络质量相对较好。
  • 机房网关安全策略和试验环境差异。

结合多种影响因素、性能、可控性综合考虑,我们推荐验证期间,分别部署 CloudCanal 在数据库源端和目标端环境中进行性能测试,再从实际效果选择最佳的部署方式

CloudCanal x AutoMQ 数据迁移同步

· 阅读需 4 分钟
John Li
John Li
Chief Executive Officer

简述

AutoMQ 是一款云原生消息中间件,通过对 Kafka 的存储进行云原生改造,实现不错的成本降低。

CloudCanal 最近接入了 AutoMQ,打通了多个数据同步链路,为用户使用 AutoMQ 助一臂之力。

本文将首先简要介绍 AutoMQ 的技术背景,然后通过 MySQL -> AutoMQ 链路展示其功能和优势。

为什么接入 AutoMQ ?

高度兼容 Kafka

AutoMQ 基于云原生将 Kafka 存储分离至对象存储,在保持与 Kafka 高度兼容的前提下,实现了不错的成本降低和资源弹性。

用户能够在不改变现有架构的情况下,轻松切换到 AutoMQ,同时享受到 AutoMQ 提供的额外优势。

性能与成本效益

AutoMQ 的计算层(Broker)是无状态的,支持 自动扩缩容自我平衡秒级分区重新分配

CloudCanal 做了哪些事 ?

继承自 Kafka

得益于 AutoMQ 的功能语义与 Kafka 高度兼容的特性,AutoMQ 相关链路沿用原 Kafka 数据管道迁移数据,使得其与 Kafka 相对应链路的特点与优势都继承了下来。

  • Topic 自动创建:目前任务支持自动创建 Kafka 的 Topic,并且能自定义分区数量。

  • 数据批量写入:支持对同一表的相同操作合并到同一条消息体中,实现数据批量写入,从而减少网络带宽的使用,提高数据处理的效率。

打通关键链路

CloudCanal 目前实现了多个关键数据同步链路:

  • MySQL -> AutoMQ:快速从 MySQL -> Kafka 转变为 MySQL -> AutoMQ,享受 AutoMQ 云原生的便利。

  • Kafka -> AutoMQ:快速从 Kafka 迁移到 AutoMQ,轻松实现技术升级。

  • AutoMQ -> AutoMQ:为 AutoMQ 之间提供数据同步,并确保数据的实时性和稳定性。

其他链路还包括 AutoMQ -> Kafka 和 AutoMQ -> MySQL,CloudCanal 后续会打通关于 AutoMQ 的相关链路,满足用户的多样化需求;如果有特定的链路需求,欢迎提出。

操作示例

准备 CloudCanal

准备 AutoMQ

  • 参考 AutoMQ 安装文档 在 Docker 上部署 AutoMQ 集群。

  • 将 cloudcanal-sidecar 容器连接到 automq_net 网络。

    docker network connect automq_net cloudcanal-sidecar

添加数据源

  • 登陆 CloudCanal 平台,选择 数据源管理 -> 新增数据源
  • 将源端 MySQL 和目标端 AutoMQ 分别添加;Docker 创建的 AutoMQ 集群,网络地址填写 broker1:9092broker2:9092

创建同步任务

  • 同步任务 -> 创建任务,选择对应的数据源,进行连接测试。
  • 点击下一步,选择任务类型以及规格,规格建议 2G 及以上。
  • 点击下一步,选择希望进行同步的表。
  • 继续点击下一步,直到创建任务。
  • 任务结构迁移、全量迁移、增量同步,正常运行.

常见问题

AutoMQ 测试链接报错

  • 需要将 cloudcanal-sidecar 容器连接到 automq_net 网络中。

    docker network connect automq_net cloudcanal-sidecar
  • 检查网络地址是否正确,示例中 Docker 创建的 AutoMQ 集群,网络地址填写 broker1:9092broker2:9092

AutoMQ 支持哪些消息格式

总结

本文介绍了 CloudCanal 与 AutoMQ 的整合,并通过 MySQL -> AutoMQ 展示其能力。

Sap Hana 数据迁移同步优化

· 阅读需 5 分钟
Barry
Chief Technology Officer

简述

CloudCanal 近期对 Hana 源端链路做了新一轮优化,优化点主要来自用户实际场景使用,这篇文章简要做下分享。

本轮优化主要包含:

  • 新增任务级增量表
  • 新增增量表定时清理能力
  • 新增增量表表结构自动演进能力
  • 任务延迟判定优化
  • Hana 1.x 的兼容
  • 产品化和文档优化

优化点

任务级增量表

CloudCanal Hana 源端任务原本不支持修改默认增量表,导致不同任务的触发器将增量数据写入同一个表,不同任务将相互影响。

比如,A 任务订阅的表积压大量数据,将影响B,C,D等订阅相同表的任务增量同步效率。

为解决这一问题,本轮优化支持 每个任务可单独设置增量表 ,以此确保任务之间互不影响。

image.png

增量表定时清理

触发器将增量数据写入增量表后,若未及时清理,可能导致空间占用增加。

在之前的版本中,用户只能手动定期清理,过程繁琐且具备一定风险(清理错)。

本轮优化增加设置任务参数 triggerDataCleanEnabled 打开自动定时清理增量表功能,并提供两个参数进行控制:

  • triggerDataCleanIntervalMin:增量表清理间隔(单位:分钟)
  • triggerDataRetentionMin:增量表数据保留时间(单位:分钟)

通过这套机制,用户能够灵活控制增量表的清理操作,同时确保未消费的增量数据不会被意外清除。

image.png

增量表自动演进

Hana 增量任务创建时自动生成增量表,CloudCanal 依赖于增量表实现各种能力,但随着 CloudCanal 版本更新,可能对增量表进行变更(比如加入新字段)。

由此带来的问题是:用户在更新 CloudCanal 后需要手动执行 DDL 以适应增量表结构的变化,若存在大量增量表,操作相当复杂。

为解决此问题,CloudCanal 新增 增量表结构 DIFF 能力,在任务启动时 自动生成差异 DDL 实现对增量表的自动演进

image.png

延迟判定优化

Hana 源端增量同步使用位点(增量表自增ID)来判断延迟,当位点向前推进时可准确获取延迟,但若无变更事件导致位点不更新,延迟会持续增大,实际上并未发生延迟。

为解决这一问题,本轮优化 通过查询增量表来判断是否存在延迟,具体逻辑为:

  • 若存在数据,系统根据增量数据的时间戳计算延迟。
  • 若无数据,任务获取当前时间发送心跳事件,并根据心跳上的时间戳计算延迟。

时间戳仅在重置位点时才用于数据查找,且在查找时进行时区转换处理。

Hana 1.x 的兼容

CloudCanal 之前版本只支持 Hana 2.x 版本,但是随着用户使用,我们发现一些用户还是在使用 Hana 1.x 版本。

Hana 1.x 版本的触发器和 2.x 存在一定的差异,且元信息获取逻辑也不同

本轮优化对上述差异点进行了兼容性优化,使 CloudCanal 能够比较全面的支持 Hana 1.x 和 2.x 版本的数据同步。

产品化增强

本轮优化除了内核层面增强,对产品能力和文档做了一系列优化,有效解决用户在数据源添加、任务创建等环节中常见的权限问题。

这些优化举措让用户创建迁移同步链路更加流畅,节省时间。

未来方向

更多目标链路

目前 Hana 支持的目标端有 MySQLStarrocksDoris 等,接下来的版本将打通 TiDBOceanBaseAdbForMySQL 等目标链路,这个需求主要来自于用户。

优化多字段触发的处理速度

在处理多字段表(单个表 300+ 字段)时,目前触发器的执行效率不满足预期,导致 DML 操作速度较慢,我们后续将对触发器模板进行性能优化,以提高处理速度。

总结

本文简要介绍 CloudCanal 近期对 Hana 源端数据同步的优化,以及链路未来的方向,希望对读者有所帮助。

Sap Hana 数据迁移同步优化(二)

· 阅读需 5 分钟
John Li
John Li
Chief Executive Officer

简述

CloudCanal 近期对 Hana 源端链路做了新一轮优化,这篇文章简要做下分享。

本轮优化主要包含:

  • 表级别 CDC 表
  • 表级别任务位点
  • 表级别触发器

单 CDC 表的问题

CloudCanal 在实现 Hana 源端增量同步时,最初采用的是单 CDC 表的模式。

即所有订阅表的增量数据(插入、更新、删除)通过触发器统一写入同一张 CDC 表。这样设计的初衷是简化架构和实现,但是同时也带来了一些问题。

  • 触发器执行效率低:采用单个 CDC 表时,我们将订阅表的字段值拼接成 JSON 字符串;虽然这种方式统一,但增加了触发器的复杂性。当字段数量超过 300 个时,会导致触发器效率显著下降,影响同步性能。

  • 增量数据积压:所有订阅表的变更数据集中写入单个 CDC 表,当 A 表增量数据较多而 B 表较少时,混合写入会导致无法及时处理 B 表数据,造成 B 表数据积压,影响同步及时性。

优化点

表级别 CDC 表

本次优化实现了表级别的 CDC 表设计,每张源表都对应一张 CDC 表,CDC 表的结构仅在原表结构的基础上增加了几个位点字段,用于增量同步。

原表

CREATE COLUMN TABLE "SYSTEM"."TABLE_TWO_PK" (
"ORDERID" INTEGER NOT NULL ,
"PRODUCTID" INTEGER NOT NULL ,
"QUANTITY" INTEGER,
CONSTRAINT "FANQIE_pkey_for_TA_171171268" PRIMARY KEY ("ORDERID", "PRODUCTID")
)

CDC 表

CREATE COLUMN TABLE "SYSTEM"."SYSTEMDB_FANQIE_TABLE_TWO_PK_CDC_TABLE" (
"ORDERID" INTEGER,
"PRODUCTID" INTEGER,
"QUANTITY" INTEGER,
"__$DATA_ID" BIGINT NOT NULL ,
"__$TRIGGER_ID" INTEGER NOT NULL ,
"__$TRANSACTION_ID" BIGINT NOT NULL ,
"__$CREATE_TIME" TIMESTAMP,
"__$OPERATION" INTEGER NOT NULL
);
-- other index

触发器 (INSERT)

CREATE TRIGGER "FANQIE"."CLOUD_CANAL_ON_I_TABLE_TWO_PK_TRIGGER_104" AFTER INSERT ON "SYSTEM"."TABLE_TWO_PK" REFERENCING NEW ROW NEW FOR EACH ROW 
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
IF 1=1 THEN
INSERT INTO "SYSTEM"."SYSTEMDB_FANQIE_TABLE_TWO_PK_CDC_TABLE" (__$DATA_ID, __$TRIGGER_ID, __$TRANSACTION_ID, __$CREATE_TIME, __$OPERATION, "ORDERID","PRODUCTID","QUANTITY")
VALUES(
"SYSTEM"."CC_TRIGGER_SEQ".NEXTVAL,
433,
CURRENT_UPDATE_TRANSACTION(),
CURRENT_UTCTIMESTAMP,
2,
:NEW."ORDERID" ,
:NEW."PRODUCTID" ,
:NEW."QUANTITY"
);
END IF;
END;

这样的设计 CDC 表的好处如下:

  • 表级别 CDC 表更加独立,方便进行多次订阅。
  • 触发器只需要执行 INSERT 语句,因此对于字段较多的表也能够快速执行。
  • 扫描消费 CDC 数据时,不需要做额外的处理,消费更简单。

image.png

表级别任务位点

表级 CDC 确实带来了许多好处,但在增量同步时,每个表都有自己的位点,原有的单一位点无法满足这种同步需求。

因此,CloudCanal 引入了表级别的增量同步位点,确保每个表能够消费各自对应的增量同步位点。位点的具体体现为:

[
{
"db": "SYSTEMDB",
"schema": "FANQIE",
"table": "TABLE_TWO_PK",
"dataId": 352,
"txId": 442441,
"timestamp": 1715828416114
},
{
"db": "SYSTEMDB",
"schema": "FANQIE",
"table": "TABLE_TWO_PK_2",
"dataId": 97,
"txId": 11212,
"timestamp": 1715828311123
},
...
]

这样做的好处如下:

  • 位点精细控制:每个表都有自己的增量同步位点,使得增量任务可以针对特定表进行增量重放,而不是重放所有表的数据。这样可以实现更加精细的控制,减少不必要的数据传输和处理,提高同步效率。

  • 数据并行处理:由于每个表有自己的位点,可以实现表级别的并行处理。不同表的增量数据可以同时进行处理,避免了单一位点导致的串行处理瓶颈,从而加快了同步速度。

核心同步原理

对于一个增量任务来说,源端涉及到扫描多个 CDC 表,需要保证单个表变更数据的顺序。

增量消费基础处理模型如下:

  • 根据源端订阅表数量,初始化相应数量的 Table Worker 工作线程。
  • 每个 Table Worker 根据位点消费对应的 CDC 表数据。

image.png

实际的 Table Worker 工作线程会根据 事务 ID 计算本次扫描范围,判断该范围是否有未提交的事务:

  • 如果有未提交事务:扫描线程进入等待队列,等待下一轮扫描。
  • 如果没有未提交事务:根据确定的范围消费增量数据,并更新单表任务位点。

image.png

未来方向

表级别位点产品化

位点状态在增量同步过程中至关重要,但针对表级别的位点,目前尚未提供可视化的界面;

包括重置位点等功能都尚未支持产品化能力,后续会逐步完善。

总结

本文简要介绍 CloudCanal 近期对 Hana 源端数据同步的优化,以及链路未来的方向,希望对读者有所帮助。

Oracle 数据迁移同步优化(三)

· 阅读需 4 分钟
Barry
Chief Technology Officer

简述

CloudCanal 最近再次对其 Oracle 源端数据同步进行了一系列优化,这些优化基于用户在真实场景中的反馈,具备很强的生产级别参考意义。

本文将简要介绍这些优化项,希望带给读者一些收获。

  • 增量事件 SCN 乱序问题
  • MISSING_SCN 事件干扰
  • 新增的归档日志消费模式

优化点

增量事件 SCN 乱序问题

Oracle 源端 Logminer 数据同步原理大致如下:

  • 获取所有包含当前 SCN 位点的 Redo 或 Archive 日志文件,并添加到 Logminer 中
  • 计算本次需要分析的 SCN 范围(START_SCN, END_SCN)
  • Logminer 对于 SCN 范围进行日志分析,分析结果展现在 V$LOGMNR_CONTENTS 视图中
  • 扫描 V$LOGMNR_CONTENTS 视图,转换处理后同步到目标端

image.png

老版本 CloudCanal 扫描 V$LOGMNR_CONTENTS 视图时指定了 SCN 范围进行查询,但在实际客户场景中偶发 SCN 乱序问题

同时 Oracle 官方也建议查询视图时不要进行过多的范围过滤或排序处理,以避免查询结果乱序。

因此我们首先 进行了 2 个优化 ,以此解决该问题:

  • 扫描 V$LOGMNR_CONTENTS 视图时直接查询所有记录,其 SCN 范围完全依赖于 Logminer 所指定的文件
  • 设定 Logminer 分析的步长参数(logMiningScnStep)控制分析性能

MISSING_SCN 事件干扰

使用 Logminer 分析 Redo 日志时,有时会出现 MISSING_SCN 事件,老版本 CloudCanal 遇到该事件则会忽略,但这会导致事件漏扫从而丢数据。

MISSING_SCN 事件具体意义为

  • Logminer 分析 Redo 日志时,由于日志切换或其他特殊情况,导致部分 SCN 事件没有被 Logminer 分析到,因此在 V$LOGMNR_CONTENTS 视图中体现为 MISSING_SCN。

因此我们做了 第 3 个优化,当遇到 MISSING_SCN 事件时采取一定的策略规避漏扫问题,具体动作为:

  • 停止扫描,回退当前 SCN
  • 根据当前 SCN 重新分析和消费日志文件

image.png

重新分析后,缺失的 SCN 记录会被 Logminer 分析到,并且此类型事件出现频率较小,因此对同步效率影响非常小。

归档日志消费模式

Logminer 分析 Redo 日志时,如果 END_SCN 与最新 SCN 接近,可能会导致部分 SCN 无法被 Logminer 分析,从而出现数据丢失。

这种情况难以避免,因为很难在 Logminer 层面确定是否有 SCN 被漏掉。

CloudCanal 老版本通过设置 fallBackScnStep 参数与最新的 SCN 保持一定距离,这种做法虽牺牲了一部分实时性,但换取了数据的准确性,而该方式和 只消费归档日志模式 有一定的相似性。

归档日志不会再发生变化,从而能够保证 Logminer 分析的准确性,对于不太注重实时性的业务(比如日报),这是一个可接受的方式(增量同步的好处不光只是实时性)。

CloudCanal 第 4 个优化 即增加了只消费归档日志模式(参数:archiveLogOnlyMode)。

在该模式下, 同步任务会根据 Archive 日志文件 + SCN 双位点 的方式,以 Archive 生成的时间顺序逐个消费,这样可以保证不漏扫任何一个 Archive 文件。

image.png

未来展望

优化性能

本次优化侧重于数据的准确性,优化了 SCN 乱序问题MISSING_SCN 问题,但部分高并发场景回退 SCN 可能会导致性能下降。

所以优化性能是后续 CloudCanal Oracle 数据同步重要的一个方向。

数据订正能力

Oracle 部署形态多样,用户场景不一,数据类型复杂,在做足事前防范工作之后,事后如何补救也是非常重要的能力。

借助 CloudCanal 数据校验订正体系,后续丰富和优化 Oracle 源端数据校验和订正能力是一个重要的工作。

总结

本篇文章主要介绍 CloudCanal 对于 Oracle 源端数据同步的深度优化,希望对读者有所帮助。

StarRocks 源端全量迁移并行读取数据

· 阅读需 3 分钟
John Li
John Li
Chief Executive Officer

简述

CloudCanal 近期支持了 StarRocks 源端全量迁移时从各 BE 节点并行读取数据的能力,相较于常规的单点数据串行读取,大大提高了数据读取效率及稳定性。

技术点

并行读取 BE 节点数据

CloudCanal 先从 FE 节点获取查询计划 (Query Plan),得到分片元数据信息,然后将获取到的分片元数据信息作为参数,下发至 BE 节点,最后获取 BE 节点返回的数据。

相较于常规的 FE 单点数据串行读取,并行读取有两点比较明显的优势,一是大幅提高效率,二是单次查询可控,避免单次查询数据量过大,导致 BE 节点内存溢出。 img3

BE 节点级别的断点续传

CloudCanal 会记录每个 BE 节点是否已读取完成。当任务失败或者中断后重启时,CloudCanal 可以过滤已经读取完成的 BE 节点,继续读取数据。

操作示例

步骤 1: 安装 CloudCanal

请参考 全新安装(Docker Linux/MacOS),下载安装 CloudCanal 私有部署版本

步骤 2: 添加数据源

  1. 登录 CloudCanal 控制台,点击 数据源管理 > 新增数据源

  2. 数据库类型选择 StarRocks,并填写 Client 地址和认证信息。

  3. 配置 额外参数

    参数描述
    feHttpAddrStarRocks FE 节点的 HTTP 地址,用于 CloudCanal 获取查询计划。例如,feNode:8030。
    beThriftAddrStarRocks BE 节点的 Thrift Server 端口。因为查询计划中得到的节点信息是 Thrift Server 的内网端口,当 CloudCanal 无法直接访问时,需要提供可访问的所有 BE 节点 Thrift Server 端口。例如,beNode1:9060,beNode2:9060...
  4. 按照上述步骤,添加目标端数据源。

步骤 3: 创建任务

  1. 点击 同步任务 > 创建任务

  2. 配置源和目标数据源,并分别点击 测试连接

  3. 选择 数据同步 并勾选 全量初始化,取消勾选 自动启动任务

  4. 选择表对应的列。

    信息

    如果需要选择同步的列,可先行在对端创建好表结构。

  5. 点击 确认创建

  6. 进入任务详情页,点击 功能列表 > 修改任务参数配置任务相关参数

    参数描述
    scanModelStarRocks 源端全量迁移扫描模式,需将参数值设为 DYNAMIC
    feHttpAddrStarRocks FE 节点的 HTTP 地址,用于 CloudCanal 获取查询计划。
    beThriftAddrStarRocks BE 节点的 Thrift Server 端口。例如,beNode1:9060,beNode2:9060...(无法访问 StarRocks 内网时的备用方案)。
    keepAliveMinStarRocks 查询任务的保活时间(单位:分钟),默认为 10 min。
    queryTimeoutStarRocks 查询任务的超时时间(单位:秒),默认为 600s,数据量大的时候需要调大该参数。
    memLimitStarRocks BE 节点中单个查询的内存上限(单位:MB),默认为 1024 MB。
  7. 点击 同步任务。选择对应的任务,点击 启动

  8. 等待全量任务完成。

CloudCanal x Hive 构建高效的实时数仓

· 阅读需 5 分钟
John Li
John Li
Chief Executive Officer

简述

CloudCanal 最近对于全周期数据流动进行了初步探索,打通了 Hive 目标端的实时同步,为实时数仓的构建提供了支持,这篇文章简要做下分享。

  • 基于临时表的增量合并方式
  • 基于 HDFS 文件写入方式
  • 临时表统一 Schema
  • 任务级的临时表

基于临时表的增量合并方式

Hive 目标端写入方式和 Doris 相似,需要在目标表上额外添加一个 __op(0:UPSERT,1:DELETE)字段作为标记位,实际写入时会先将源端的变更先写入临时表,最终合并到实际表中。

CloudCanal 的设计核心在于,每个同步表对应两张临时表,通过交替合并的方式,确保在一张临时表进行合并时,另一张能够接收新变更,从而提升同步效率和并发性。

image.png

Hive 提供了两种合并方式:INSERT OVERWRITE(所有版本均支持),MERGE INTO(Hive 2.2.0 之后支持且需要是 ACID 表)

-- INSERT OVERWRITE 语法
INSERT OVERWRITE [LOCAL] DIRECTORY directory1
[ROW FORMAT row_format] [STORED AS file_format]
SELECT ... FROM ...

-- MERGE INTO 语法
MERGE INTO <target table > AS T USING < source expression / table > AS S
ON <boolean expression1>
WHEN MATCHED [AND <boolean expression2>] THEN
UPDATE SET <set clause list>
WHEN MATCHED [AND <boolean expression3>] THEN
DELETE
WHEN NOT MATCHED [AND <boolean expression4>] THEN INSERT VALUES<value list>

任务级的临时表

在大数据场景下,多表汇聚的情况十分普遍,CloudCanal 在构建临时表时,利用源端的订阅 Schema Table 信息,创建不同的临时表。

通过这种方式,无论是相同或不同的任务、相同或不同的 Schema(源端)、相同或不同的 Table(源端),都能将数据写入不同的临时表,最终合并到同一个实际表中,互相之间不会产生影响。

image.png

基于 HDFS 文件的写入方式

Hive 是建立在 Hadoop 体系上的数据仓库,而实际的数据存储在 HDFS 中。

如果直接通过 HQL 将增量数据写入 Hive,Hive 会将 HQL 转化为 MR Job,由于每一个 MR Job 处理速度相对较慢,这将导致增量性能极其差。

CloudCanal 在进行数据写入的时候,选择的是绕过 Hive 这层,直接写入 HDFS 文件系统。

目前支持 HDFS 文件格式:Text、Orc、Parquet。

临时表统一 Schema

基于临时表构建的增量方式,如果临时表分散在不同的 Schema 中,将给 DBA 的管理带来不便。

为了简化管理,CloudCanal 将所有临时表构建在统一的 Schema 下,并允许用户自定义其临时表路径。

示例

准备 CloudCanal

添加数据源

  • 数据源管理 -> 添加数据源, 添加 MySQL、Hive

    image.png image.png

创建同步任务

  • 选择源端 MySQL 和目标端 Hive,同步的 SchemaTable,高级参数含义参考 MySQL -> Hive

    image.png

  • 任务创建第四步,点击 配置分区键

  • 选择 分区键类型 以及 HDFS 文件类型

    image.png image.png

  • 点击下一步,创建任务即可

    image.png

未来方向

文件 Append 写入方式

目前 HDFS 文件写入处理,是每批数据写到一个文件中,并不会处理历史数据文件,更加合理的方式是基于历史文件进行 Append 追加,写满之后再切换为下一个文件。

提供参数优化 MR 处理速度

目前 CloudCanal 并没有提供参数入口用于优化 MR 处理速度,而是自动使用用户所配置的,未来 CloudCanal 将提供一个参数入口用于用户自定义每一个 MR Job 的处理并行度等优化参数。

支持 MERGE INTO 合并方式

目前 CloudCanal 仅支持 INSERT OVERWRITE 的合并方式,这种方式更为通用,而 MERGE INTO 此种合并方式速度更快,但限制较多,未来 CloudCanal 也会支持此种合并方式。

支持自定义分区键

目前 CloudCanal 仅支持按照日期选择分区键,目前暂时不支持更多分区键的选择,未来 CloudCanal 会提供更多分区键的选择。

总结

本篇文章简单介绍 CloudCanal 对于全生命周期的数据流动的初步探索,并通过 MySQL -> Hive 示例介绍其使用。

Redis 数据迁移同步优化

· 阅读需 4 分钟
Barry
Chief Technology Officer

简述

CloudCanal 前一段时间支持了 Redis 到 Redis 数据迁移同步能力,并支持其双向同步,但是支持的指令种类有限。

随着用户使用,指令支持不全面成为一个比较大的问题,所以最近的版本,我们对此能力,结合用户实际碰到的问题,进行了新一轮优化。

此轮优化的特点是:

  • 增加数据初始化的类型
  • 增加数据同步的指令种类
  • 双向同步策略优化

本文简要介绍以上优化点,并展望该链路未来的研发方向,希望对用户使用有所帮助。

优化点

指令支持范围提升

Redis 到 Redis 数据同步在原先支持 Set、Hset、Del、Hdel、Expire 五种指令的基础上,额外支持了 Sadd、Zadd、LPushRename、Incr、Incrby、Hsetnx、Hmset、Lpush、Rpush、Lset、Zrem、Zremrangebyscore 12 种命令。

数据初始化(FULL SYNC)在原先支持 String、Hash 类型基础上,额外支持 List、Set、ZSet 三种类型。

数据同步指令种类的丰富,以及数据初始化类型多样化,让此链路具备更好的可落地性。

指令优化

对于 List 类型数据初始化,因获取的成员数据默认倒序,CloudCanal 会对其内部成员进行 重新排序,然后使用 RPush 命令将数据统一写入目标端,确保源、目标数据准确。

对于 Expire 指令,数据同步如果直接应用到目标端,会导致目标端数据过期晚于源端,因此 CloudCanal 在处理这类命令时,将 Expire 转换为绝对时间命令 PExpireAt,从而实现源对端 Key 同时过期。

image.png

双向同步防循环优化

优化前,Redis -> Redis 双向同步防循环策略采用 辅助指令进行判定,当收到正常指令,计算 hash 值,构建辅助指令,以反查辅助指令 key 是否存在进行数据过滤。

这种策略存在以下问题:

  • 辅助指令过期时间不好把控
  • 辅助指令会占用内存空间
  • 辅助指令未过期会导致同样的命令失效

而此次优化,总体延用辅助指令策略,但采用 删除辅助指令 判定是否进行数据过滤,虽然会导致性能下降,但能解决上述三个问题,在缓存写入量不大的情况下,效果良好(缓存常用场景读多写少)。

新策略的好处:

  • 无需考虑辅助指令过期问题
  • 能支持大部分指令防循环(Incr、IncrBy等)

image.png

指令解析 / 处理优化

本次优化对于指令解析、处理结构进行进一步重构,单个指令需要实现的逻辑更加清晰、独立,对于新指令添加,更加方便,为后续加快指令集支持打好基础。

演进方向

丰富指令集

CloudCanal 目前支持 17 种 Redis 常用指令,但仍然只是 Redis 指令集冰山一角,后续我们将支持更多 Redis 指令同步(单向 / 双向)。

数据校验和订正

目前 Redis 到 Redis 链路 暂未开通数据校验和订正功能,对于数据迁移同步产品,事后补救和事前防范(同步逻辑的严谨性)同等重要,后续我们将补上这部分能力。

单独全量功能

目前 Redis 到 Redis 链路并没有开通单独的全量迁移能力,而是在增量任务中顺带完成全量迁移(FULL SYNC),对于部分用户,需要针对该链路进行定时备份(周期性全量迁移),此功能是需要的。

总结

本文简要介绍了 CloudCanal 近期对于 Redis 到 Redis 单向和双向同步链路的优化,并展望该链路未来的研发方向,希望能为用户构建在线数据生态和数据应用发挥一定的作用。

CloudCanal 同步 Debezium 数据实战

· 阅读需 6 分钟
John Li
John Li
Chief Executive Officer

简述

Debezium 是一个开源的数据订阅工具,主要功能为捕获数据库变更事件发送到 Kafka

CloudCanal 近期实现了从 Kafka 消费 Debezium 格式数据,将其 同步到 StarRocks、Doris、Elasticsearch、MongoDB、ClickHouse 等 12 种数据库和数仓,补全其数据到达能力。

本文将先简单介绍该项技术实现的背景,再通过 MySQL -> Kafka -> Starrocks 示例展示此功能。

image.png

为什么要消费 Debezium 格式数据

高流行度

Debezium 是一个高质量、被大量项目集成的开源项目,社区用户活跃,官方维护积极,修复 bug、增加新特性,不断更新版本。

作为 Kafka Connect 生态系统的一部分,Debezium 能够无缝与 Kafka 进行对接,为用户后端数据处理提供了强大的 实时数据准备 能力。

由此形成的高流行度,让每一个数据行业从业者不能忽视其影响力。

合理的消息结构

Schema(数据结构) 遵循 Kafka Connect 标准,提供了详细的字段信息。

"schema": {
"type": "struct",
"fields": [
{"type": "int32", "optional": false, "field": "id"},
{"type": "string", "optional": false, "field": "name"},
{"type": "int32", "optional": false, "field": "age"}
],
"optional": false,
"name": "my_database.user.Value"
}

Payload(数据)包含实际的数据库变更数据,与 Schema 中定义的字段对应。

"payload": {
"id": 123,
"name": "John Doe",
"age": 30,
"source": {
...
}
}

此外消息还携带了源端数据源全面的关联信息,包括库、表、时间戳、位点等信息。整体格式实用、简洁。

支持 Schema 演进

Debezium 不仅捕获数据库模式的当前状态,还能感知和记录每次模式变更细节。

当数据库表结构发生变化时(如添加、删除、修改字段等),Debezium 能够 实时捕获这些结构变更,确保变更事件的精准传递。

另外 Debezium 会为每个捕获的变更事件 记录包含当前和先前 Schema 的历史记录

这意味着 可追溯任何时刻数据库 Schema,了解特定时间点表字段、数据类型等信息, 并且可精准还原数据库在某一时刻的结构,无需额外的查询或推测。

CDC 数据格式标准

Debezium 数据 Schema 基于 Kafka Connect 标准设计,这使 Debezium 产生的变更事件能够轻松地集成到各种 Kafka Connect 连接器中,实现了与 Kafka 生态系统的顺畅对接。

这个设计使得 Debezium 数据 Schema 有望成为 CDC(Change Data Capture) 领域标准,为实时数据流的流动提供了基础设施。

端到端的缺憾

Debezium 集如此众多的优点,但是其官方缺少消息到对端的能力(目前有在补充),这让一部分用户感觉束手无策,CloudCanal 支持消费 Debezium 数据即解决这个问题,为用户实时数据生态建设贡献绵薄之力。

支持 Debezium 的主流 CDC 技术比较

对于使用 Debezium 的用户来说,消费 Kafka 中的 Debezium 数据并将其写入其他数据源,有几种主流 CDC 技术可选,如下表。

Kafka-ConnectFlink-CDCCloudCanal
同步配置配置文件代码/配置(新版本)可视化
同步性能(延迟)优秀优秀优秀
社区支持一般积极积极
大规模部署使用一般优秀优秀
消息格式符合其标准的 JSON、Avro...Debezium JSON、Canal JSON、Maxwell JSONDebezium JSON、Canal JSON、CloudCanal JSON 等
插件支持Oracle、MySQL、SqlServer...Oracle、MySQL、SqlServer...StarRocks、Doris、Elasticsearch 等 12 种

CloudCanal 支持 Debezium 做了那些事

CloudCanal 之前即实现了将数据库数据以 Debezium 格式写入目标端 Kafka 的能力,并在兼容性方面做了大量优化。

此次版本更新则支持从 Kafka 消费 Debezium 格式数据,并同步到对端数据库或数仓, 形成基于 Kafka 中转的端到端数据迁移同步能力,同时可平滑对接上/下游已使用其他工具且以 Debezium 数据格式载体的需求。

操作示例

Debezium 环境准备

  • 相关资源一键部署 (Docker): debezium-sync-my2sr.tar.gz
    • Kafka 集群 + Kafka UI
    • Debezium
    • MySQL (源端)
    • Starrocks (目标端)
    tar -xzvf debezium-test.tar.gz
    sh install.sh

创建 MySQL Source Connector

  • 源端是 MySQL,通过下面的表进行创建。

    CREATE DATABASE `inventory`;

    CREATE TABLE `inventory`.`customer` (
    `c_int` int NOT NULL,
    `c_bigint` bigint NOT NULL,
    `c_decimal` decimal(10,3) NOT NULL,
    `c_date` date NOT NULL,
    `c_datetime` datetime NOT NULL,
    `c_timestamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `c_year` int NOT NULL,
    `c_varchar` varchar(10) NOT NULL,
    `c_text` text NOT NULL,
    PRIMARY KEY (`c_int`)
    );
  • 通过 Debezium 的 Api 接口创建 Connector 订阅 MySQL 的变更事件。

    curl -i -X POST http://127.0.0.1:7750/connectors \
    -H 'Content-Type: application/json' \
    -d '{
    "name": "connector-test-mx",
    "config": {
    "connector.class": "io.debezium.connector.mysql.MySqlConnector",
    "database.hostname": "112.124.38.87",
    "database.port": "25000",
    "database.user": "root",
    "database.password": "123456",
    "database.server.id": "1",
    "database.server.name": "mx",
    "database.include.list": "inventory",
    "topic.prefix": "mx",
    "table.include.list": "inventory.customer",
    "snapshot.mode": "never",
    "database.history.kafka.bootstrap.servers": "112.124.38.87:19092,112.124.38.87:29092,112.124.38.87:39092",
    "schema.history.internal.kafka.bootstrap.servers": "112.124.38.87:19092,112.124.38.87:29092,112.124.38.87:39092",
    "schema.history.internal.kafka.topic": "mx.schemahistory.customer",
    "database.history.kafka.topic": "mx.mx_history_schema",
    "include.schema.changes": "false"
    }
    }'
  • 创建后,查看 Connetor 的状态。

    curl -s http://127.0.0.1:7750/connectors/connector-test-mx/status

CloudCanal 订阅 Kafka 的数据变更

准备 CloudCanal

添加数据源

  • 数据源管理 -> 添加数据源, 添加 Kafka、Starrocks、MySQL image.png image.png image.png

创建同步任务

  • **任务管理 **-> 新建任务

  • **Kafka **选择 **Debezium Envelope Json Format **格式

  • 该消息格式的说明,参见:源端 Kafka Debezium Json 使用说明 image.png image.png

  • Kafka 消息中如果有 Schema,需要在 任务详细 -> 参数修改 -> 源数据源配置 中修改 envelopSchemaIncludetrue image.png

同步测试

  • 源端数据库做数据变更,Debezium 将数据写入 Kafka 后,CloudCanal 会写入到 Starrocks 中。 image.png

  • 数据同步结束后校验 MySQL 和 Starrocks 的数据,40 万左右的数据是一致的。 image.png

总结

本文介绍了 CloudCanal 支持消费 Debezium 格式数据的背景,以及通过 MySQL -> Kafka -> Starrocks 示例介绍其使用。

ElasticSearch 对端同步技术详解

· 阅读需 5 分钟
John Li
John Li
Chief Executive Officer

简介

CloudCanal 对于 Elasticsearch 的支持经历了很多轮迭代,版本一路从 6.x,7.x 支持到 8.x 版本,也适配了其纷繁多样的 API。

因为 Elasticsearch 是一个相当流行的、实时的、并且具备一定不可替代能力的搜索引擎,所以很有必要对比下市面上我们能够比较容易获得的、免费的数据迁移同步工具,让大家落地实时数据搜索和分析更加有信心。

本文即从一个比较窄但是应用广泛的场景 - MySQL 到 Elasticsearch 数据同步技术 - 切入,比较不同技术的优劣和相关技术细节,最后给到一些展望。

Elasticsearch 数据迁移同步技术对比

目前能够比较容易获得的、免费的、并且有一定应用范围的数据迁移同步工具有:Logstash 和 FlinkCDC,CloudCanal 也算其中之一。

一些对比如下表(如有错误,可联系笔者进行修改)。

LogstashFlinkCDCCloudCanal
产品化基础基础完备
高可用
任务创建配置文件配置文件 + 代码可视化
监控告警基础基础完备
索引(结构)迁移
全量迁移
实时同步
数据校验
索引结构同步(DDL)有限(加列)
索引定义依赖
数据源插件(原厂)一般一般丰富
数据源插件(社区)丰富一般
供应商原厂第三方第三方
获取方式开源开源免费社区版

综合来看,各个产品各有特点,并且有自己的局限性。

Logstash 和 FlinkCDC 更多偏向社区,但是他们背后庞大的商业产品体系(分别对应 ElasticSearch 和 阿里云 MaxCompute & Dataworks)注定两者定位仅仅是支撑工具。

CloudCanal 更加偏商业化些,但是背后公司以此谋生。

CloudCanal Elasticsearch 迁移同步技术介绍

基于 index mapping(索引结构)

因为 CloudCanal 最初支持从结构化数据库 - MySQL、Postgres、TiDB 等迁移同步数据到 Elasticsearch ,所以采用基于 mapping 方式构建目标数据。

具体展开,即在迁移同步数据到 Elasticsearch 前,CloudCanal 读取源端表结构,自动生成对应的 Elasticsearch 映射定义,并在对端创建,即结构迁移。

全量迁移和增量同步中,CloudCanal 会强依赖目标端的 mapping 结构进行数据构建。

基于 index mapping 方式构建目标数据带来的额外好处是:在 Elasticseach 上保持源端所有字段高速可查特性,叠加其对字符串字段基于倒排索引所带来的模糊查询能力。

处理 mapping 的变化 (DDL)

在关系型数据库同步到 Elasticsearch 过程中,源端表结构可能会动态变更,例如添加新字段等 DDL 操作。

对于 index 的 dynamic 参数设置为 false 后,Elasticsearch 将无法自动更新该结构变更,这将导致新的字段数据无法基于索引进行检索。

为了解决这一问题,CloudCanal 支持同步源端 DDL 加列的变更操作 - DDL 语句转换成 Elasticsearch 操作,动态更新到 index 的 mapping 中。

动态更新 mapping 的好处在于:

  • 保证两端结构一致,满足业务的动态变更需求
  • 无需用户手动干预构建索引,方便用户直接利用最新字段进行查询分析
  • 有效弥补了 Elasticsearch 映射静态的限制

客户端 API 选择与得失

CloudCanal 依赖 Elasticsearch Java SDK 进行结构和数据操作,没有使用其基础 REST API 进行新的封装和调用。

这样做带来的好处是更少的工作量和更好的性能,坏处是 Java SDK 随着 Elasticsearch 版本升级变化极大,导致 CloudCanal 需要做较多的驱动隔离工作。

从 CloudCanal 架构设计原则上来看 - 不直接依赖开源/商业的业务组件,依赖数据库官方驱动 - 我们应该做了正确的事情。

CloudCanal Elasticsearch 数据迁移同步展望

丰富源端数据源

目前 CloudCanal 支持 MySQL (或 MySQL 包装产品)、Postgres、TiDB、Kafka 同步到 Elasticsearch。

后续支持更多的源端数据源是一项非常重要的工作,且不仅限于结构化数据源,更有半结构化(mongodb)、非结构化数据源(redis、text file 等)作为源端的迁移同步,而后者对于基于 index mapping 的数据迁移同步带来很大的挑战。

Elasticsearch 源端数据同步

CloudCanal 尚未实现对 Elasticsearch 进行源端数据同步功能,但是我们收到了蛮多社区用户和商业用户此类需求。

当前类似 Logstash 实现的也仅仅是全量数据迁移(使用 logstash-input-elasticsearch 插件),增量同步尚无合适方案,基于 trigger(如有)或定时基于时间戳增量扫描可能是解决方式。

基于 store 构建目标数据

CloudCanal 后续将支持基于 store 构建目标数据,即直接将 doc 写入目标端的存储文件中,不再依赖索引的 mapping 结构。

基于 store 构建目标数据好处在于:

  • 支持同步非结构化数据,实现对各类数据源的通用同步
  • 用户可以自行决定索引的构建和查询逻辑,更轻松实现各类数据分析场景

总结

Elasticsearch 带给业务独特的数据检索体验,是业务数据操作重要一环。CloudCanal 通过长周期、多轮迭代以及业务应用反馈予以鼎力支持,并由此积累了部分经验,借此文章对外分享。

CloudCanal x Db2 数据迁移同步

· 阅读需 5 分钟
John Li
John Li
Chief Executive Officer

简述

Db2 是一款具有悠久历史的关系型数据库,由 IBM 公司开发和维护,广泛应用于金融级业务场景。

CloudCanal 近期提供了 Db2 为源端的数据迁移同步 功能,用户可以便利地将 Db2 中数据实时同步到其他数据库,实现数据更广泛、更实时的应用。

功能介绍

目标数据库和能力

目标端数据源结构迁移数据初始化增量同步数据校验数据订正
MySQL支持支持支持支持支持
TiDB支持支持支持支持支持
Kafka-支持支持--
StarRocks支持支持支持支持支持

Db2 源端特色能力

基于 CDC 技术的数据同步

Db2 源端同步能力是基于 SQL 复制的 ASN 捕获代理,CloudCanal 通过捕获 Db2 CDC 表中的增量数据来实现数据同步。

Db2 源端进行增量数据同步时,CDC 元信息表的维护过程会被自动化管理,无需用户手动操作。

同时,CloudCanal 会周期性地清理已经同步到目标端的 CDC 记录,以避免 CDC 表的无限增长,从而保证同步数据的准确性和系统的稳定性。

结构迁移类型自动处理

不同数据库对于数据类型支持存在差异,CloudCanal 结构迁移时会进行类型自动转换

Db2 为源端的结构迁移也存在类似转换(5+,并不断细化),如对端为 MySQL 或 TiDB,CloudCanal 将自动转换 VARCHAR FOR BIT DATA 为 VARBINARY。

数据初始化支持断点续传

Db2 为源端的数据初始化,支持字符或数字类型主键表的断点续传功能。

对于亿级别数据量的大表,此能力不可或缺,数据初始化断点续传功能让此种暂停尽可能少的影响进度。

数据同步支持断点续传

长周期的数据同步任务,暂停任务调整参数修复问题数据优化性能等情况很难避免,断点续传让这些维护操作变成可能。

CloudCanal 定时或定量保存提交后的位点(LSN,log sequence number),确保增量同步任务重启后可继续,并且不丢失数据。

配套数据校验与订正能力

在数据同步过程中,由于数据的外部关联性结构约束差异数据库运维操作软件bug等情况,两端数据可能会不一致,此时数据校验和订正功能非常必要。

CloudCanal 为 Db2 为源端的数据同步能力额外提供了数据校验数据订正功能,快速确定不一致数据范围,并针对差异数据进行修复。

产品化能力支撑

可视化创建

CloudCanal 创建 Db2 数据迁移同步任务是完全可视化的,通过获取数据库元数据,让用户在 web 页面上决定哪些库、表、列进行迁移同步,或者设定过滤条件自定义数据处理逻辑等。

自动化流程

Db2 数据迁移同步任务创建后,CloudCanal 将自动流转各个阶段的任务,用户无需干涉,直达数据实时同步状态。

监控图表支撑

CloudCanal 为 Db2 数据迁移同步任务提供了多个实用监控指标,包括增量缓存RPS增量缓存延迟(ms)内存队列数据个数等,当调优任务性能或排查任务异常原因时,监控指标提供了很好的判断依据。

告警支持

CloudCanal 为 Db2 数据迁移任务提供了包括钉钉/企业微信/飞书/自定义等 webhook 类型告警,对于企业级客户,可额外选择邮件,以及短信告警,实时保障同步任务的高可用。

简单示例

本示例以将数据从 Db2 数据库同步到 MySQL 数据库为操作案例,以便更好地说明 CloudCanal 在不同数据库之间进行数据同步的能力。

准备动作

任务创建

  • 任务管理 -> 新建任务

  • 测试链接并选择 源 和 目标 数据库

  • 点击下一步

  • 选择 数据同步,并勾选 全量数据初始化,其他选项默认

  • 选择需要迁移同步的表和列

  • 确认创建任务

  • 任务自动做结构迁移、全量迁移、增量同步

  • 增量阶段进行数据写入后,进行数据校验,数据校验通过

总结

本文主要介绍了 CloudCanal 支持 Db2 为源端数据迁移同步功能,通过这个能力,用户可以便利地将 Db2 中数据实时同步到其他数据库,实现数据更广泛、更实时的应用。

OceanBase 数据迁移同步优化(一)

· 阅读需 6 分钟
John Li
John Li
Chief Executive Officer

简述

CloudCanal 去年支持 OceanBase 数据迁移同步能力后,随着使用用户增多以及问题反馈,近期对该能力进行了一轮较大规模的优化。

本篇文章简要介绍这些优化点,以及未来该能力的演进方向。

优化点

大幅提升同步性能

CloudCanal 目前使用 OceanBase LogProxy 做增量数据订阅,使用方式相对简单明了。

@Override
public void notify(LogMessage message) {
try {
ParsedEntry entry = msgConvertor.convertMsgToEntry(message);

if (entry == null) {
return;
}

instance.getEventStore().put(entry);
} catch (Exception e) {
String msg = "parse ob msg failed.msg:" + ExceptionUtils.getRootCauseMessage(e);
log.error(msg, e);
throw new LogProxyClientException(ErrorCode.E_PARSE, msg);
}
}

消息解析对性能影响相对小,攒批对端写入方式 影响更大。

攒批方面,我们将变更事件写入内存队列后,按照 个数/容量阈值(increBatchSize)超时时间(fetchFromBrokerTimeoutMs) 刷出,提升批量写入的粒度。

对端写入方式,根据不同数据源,我们采用了 batchmultisql并行upsert 等技术提升写入效率。

统一各类表全量扫描方式

全量数据扫描 是 CloudCanal 全量数据迁移(或数据初始化)重要组成部分,需满足 性能优秀(2KB/record,>= 100k records 扫描速率)、可断点续传可预测进度表兼容性好 的要求。

其中前三者是业务要求,最后一种是尽可能满足前三者的前提下,做到更多表的兼容。

CloudCanal 碰到的"表"包含以下类型

  • 关系型数据库
    • 无/单/多主键
    • 各种类型主键(整型/浮点/日期/二进制等)
    • 差异值主键(有/无符号,null值/空值,超长值)
    • 各种类型分区
    • 差异数据量(1万,100万,1000万,1亿,10亿,100亿)
    • 实体表/视图/临时表
  • 消息中间件
    • 各种命名规范
    • 无/有分区
    • 顺序/非顺序
  • 文档数据库
    • 规范/非规范(schemaless)
    • 无/有行业规范格式(ObjectId)
  • 缓存数据库
  • 搜索引擎

CloudCanal 全量数据扫描主要面向关系型数据库,性能要求断点续传能力进度预测能力都基于主键展开。

此次优化,我们做了如下几方面工作,统一了扫描逻辑,并且让无/单/多主键、各种类型主键、分区表都可断点续传

  • 主键分区作为断点续传位点
  • 扫描语句加入分区指定(如有)元组比较(单/多主键)按元组排序指定分页数等部分
  • 对比位点最大值扫描行数方式判定扫描是否结束

此外,各个数据源可根据自身差异性,可扩展扫描语句最大最小位点值获取逻辑链接自定义(设置超时等)执行语句上下文自定义(设置fetchSize等)

支持全局索引表

全局二级索引(GLOBAL)对分布式数据库有着非常重要的作用,它让原本 多分区数据检索 操作 弱化成单分区检索,加速不同维度点查响应,提升 QPS。

对于 OceanBase 对端写入,CloudCanal 默认采用关系型数据库 INSERT IGNORE/ON DUPLICATE KEY UPDATE 规避主键/唯一键冲突

但是对于带有 GLOBAL 索引的表,OceanBase 不支持 INSERT IGNORE 操作,所以此次优化,我们写入 OceanBase 的 INSERT 操作默认改为 ON DUPLICATE KEY UPDATE (REPLACE)。

异构 DDL 同步转换优化

从异构数据库同步 DDL 到 OceanBase,我们优化成白名单模式

如 MySQL 到 OceanBase DDL 同步,默认支持

  • ALTER TABLE xxx ADD/DROP/MODIFY COLUMN
  • CREATE INDEX
  • RENAME TABLE

优化同时去除了 ALTER TABLE xxx CHANGE COLUMNAFTER/BEFORE 等 OceanBase 现阶段不支持的语句。

此项能力随着 OceanBase 产品能力的进化而不断丰富。

解决时间戳自更新问题

对于类似 gmt_create datetime/timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP 时间字段定义,当源端该字段值变化区间小于时间精度(被程序判定未变化),并且写入对端并非采用 upsert 方式(精确字段更新),那么该字段数据将不一致。

CloudCanal 在精确字段更新模式下,默认将时间字段置为更新状态,确保将源端值带到对端,解决不一致的问题。

演进方向

OceanBase 4.x 版本兼容

OceanBase 4.x 有着更加便利的部署方式和更好的使用体验,CloudCanal 后续会安排对此版本的兼容性测试,特别对于其可能存在的 订阅权限(系统租户保护)变化更多的 DDL 支持更加丰富类型支持 做出变化。

OceanBase 商业级增量组件兼容

OceanBase 商业版 OMS 的数据订阅能力有别于目前社区版的 LogProxy,如 OceanBase 官方逐步扩大其使用面,CloudCanal 将第一时间跟进兼容。

更快的数据校验和订正能力

分布式数据库相对单机数据库,单表数据量大幅度增加(亿级表相当常见),数据校验和订正性能相比数据初始化,更加依赖数据扫描的性能,为此,CloudCanal 将开放 单表分片/分区并行扫描 的能力。

更强的结构迁移和 DDL 同步能力

大表 通用/特殊化分区 是常见操作,目前 CloudCanal 对表分区的结构迁移并未有效支持,这种分区的结构迁移,对于同构数据库相当必要。后续,我们将提供 分区信息的结构迁移

更多的数据源生态支持

以 OceanBase 为源端数据迁移同步,目前支持 MySQLStarRocksOceanBaseKafka 对端,我们希望后续如 RedisElasticSearchDorisHudi 等数据源也能加入到这个目标数据源中。

总结

本文主要介绍了 CloudCanal 在过去一段时间对 OceanBase 数据迁移同步能力的优化,从而是这个能力具备更强的性能更好的兼容性更加稳定的数据迁移同步表现

深入浅出 SQL Server CDC 数据同步

· 阅读需 9 分钟
Barry
Chief Technology Officer

简介

SQL Server 是一款老牌关系型数据库,自 1988 年由 Microsoft、Sybase 和 Ashton-Tate 三家公司共同推出,不断迭代更新至今,拥有相当广泛的用户群体。

如今,我们提到 SQL Server 通常指 Microsoft SQL Server 2000 之后的版本。

SQL Server 2008 是一个里程碑版本,加入了大量新特性,包括 新的语法更丰富的类型 以及本文所提及的 CDC 能力,这个能力让数据从 SQL Server 实时同步到外部更加方便。

本文将介绍 CloudCanal 在新版本中对于 SQL Server 数据同步更进一步的优化和实践。

SQL Server CDC 长什么样?

原始日志

常见的数据库往往存在以下两种日志

  • redo 日志
    • 记录数据的正向变更,简单来说,事务的 commit 通常先记录在这个文件,再返回应用程序成功,可确保数据 持久性
  • undo 日志
    • 用于保证事务的 原子性,如执行 rollback 命令即反向执行 undo 日志中内容以达成数据回滚

一条 DML 语句写入数据库流程如下

  • 大部分关系型数据库中,一个或多个变更会被隐式或显式包装成一个事务
  • 事务开始,数据库引擎定位到数据行所在的 文件位置 并根据已有的数据生成 前镜像后镜像
  • 后镜像 数据记录到 redo 日志中,前镜像 数据记录到 undo 日志中
  • 事务提交后,日志提交位点(检查点)向前推进,已提交的日志内容即可能被覆盖或者释放

SQL Server redo/undo 日志采用了 ldf 格式 ,文件循环使用。

  • ldf 日志文件由多个 VLF(逻辑日志) 组合在一起,这些 VLF 首尾相连形成完整的数据库日志记录
  • ldf 在逻辑日志末端到达物理日志文件末端时,新的日志记录将回到物理日志文件开始,复写旧的数据

ldf 文件即 CDC 所分析的增量日志文件。

启用 CDC

在数据库上执行 exec [console].sys.sp_cdc_enable_db 命令为 console 数据库启用 CDC 功能,这个语句实际上会创建两个作业: cdc.console_capture , cdc.console_cleanup

使用 exec sp_cdc_help_jobs 命令可查看这两个作业详细信息。

  • cdc.console_capture
    • 负责分析 ldf 日志 并解析 console 数据库事件,再将其写入到 CDC 表中
    • 间隔 5 秒钟执行一次扫描,每次扫描 10 轮,每轮扫描最多 500 个事务
  • cdc.console_cleanup
    • 负责定期清理 CDC 表中较老的数据
    • 默认保留 3 天 CDC 日志数据(4320秒)

开启 CDC 功能后,SQL Server 数据库会多出一个名称为 cdc 的 schema,里面会多出下列这些表。

  • change_tables
    • 记录每一个启用了 CDC 的 源表 及其对应的 捕获表
  • captured_columns
    • 记录对应 捕获表 中每个列的信息
  • index_columns
    • 记录 源表 含有的主键信息(如果有)
  • lsn_time_mapping
    • 记录每个事务的开始/结束时间及 LSN 位置信息
  • ddl_history
    • 记录源表发生的 增/减列 对应的 DDL 信息,除此之外的 DDL 都不会被记录

有了上述准备动作和信息,即可开始对原始表开启 change data capture(CDC),即增量数据捕获了。

捕获表变更

有如下 源表

create table [dbo].[test_table] (
[id] [bigint] NOT NULL primary key,
[test] [nchar](10) NULL
)

执行下列命令即可为它启用 CDC

exec [console].[sys].[sp_cdc_enable_table]
@source_schema = [dbo],
@source_name = [test_table],
@role_name = NULL,
@capture_instance = [dbo_test_table], -- 可选项
@supports_net_changes = 0;

cdc schema 下多出一个名为 dbo_test_table_CT 的表,即 捕获表

  • 源表 [dbo].[test_table] 做若干 DML 操作,通常是 5 秒内就可在捕获表中看到变更记录
  • 源表 做一些 增/减 列 操作,对应的 DDL 会出现在 ddl_history 表中

其他表也可通过类似设置,获取到相应的增量变更。整个机制看上去相当直观和简单。

挑战是什么?

难点1:DDL 同步困难

CDC 捕获表只反馈数据的变化,无 DDL 信息

DDL 需额外获取即和 DML 的顺序关系要额外处理

解决这个问题,需要通过执行以下的 SQL 将 DDL 和 DML 事件混合到一起并保证顺序,但是实际使用中会面临严重的性能问题。

select * from (
select __$start_lsn lsn,__$operation oper,__$update_mask mask, null ddl ,id data_id,test data_test
from [console].[cdc].[dbo_test_table_CT]
union
select ddl_lsn lsn, -1 oper,null mask, ddl_command ddl ,null data_id,null data_test
from [console].[cdc].[ddl_history]
) t order by lsn

难点2:无法获取新增列数据

CDC 捕获表的结构并不会随着 DDL 事件的发生而变化,这意味着无法获取新增列的数据

难点3:数据库限制

使用 CDC 功能本身也会产生一些硬性的限制,大致可以分为两类

硬性限制

  • 已经启用 CDC 捕获的源表上不能执行 truncate table 语句,执行即报错

  • CDC 捕获表本质上也是一个普通的表,大量订阅会导致整库表的数量扩大

  • 依赖 SQL Server 代理,如没启动或作业运行失败,捕获表中不会有任何新数据写入

  • 一张表只能创建 2 张对应的 CDC 捕获表,即无法做超过 2 个以上的增量订阅

  • 一张表的 CDC 捕获只能设置启动和禁止,即不能通过重建 CDC 并指定 LSN 来获取新数据

软性限制

  • CDC 捕获表中的数据存留时间默认 3 天

  • 在插入或更新超大字段时默认 CDC 只会处理最大 64KB 个字节的数据

    • 数据内容如果超过这个限制会导致 CDC 捕获任务报错并停止工作
    • 受影响的类型有 7 个:textntextvarchar(max)nvarchar(max)varbinary(max)xmlimage

CloudCanal 的解决方法

CloudCanal SQL Server 增量消费基础处理模型如下所述,保证单个表的数据变更顺序,满足大部分场景

  • 根据 change_tables 表确定一个工作队列
  • 确定起始位点,对于捕获表的增量数据扫描从起始位点开始
  • 并发处理工作队列上的事件
  • 每个 Worker 会根据起始 LSN 扫描自身要处理的 CDC 捕获表
  • 每个 Worker 扫描都会维护自身的 LSN 进度

解决难点1:DML/DDL重排序

CDC 捕获表中的每一条记录都有一个 LSN 信息,ddl_history 表也有 LSN 信息。因此可以借助 插值 的思想将 DDL 事件插入到正常的 DML 事件序列中去,原理如下图:

  1. ddl_history 表进行预查询,获取到的 DDL 事件在稍后的处理中会进行位点比对处理
  2. 查询 dbo_test_table_CT 数据捕获表
  3. 处理每一条的捕获表的数据时检测 DDL 事件是否可以被插入
  4. 形成完整的事件流

解决难点2:反查补充缺失数据

SQL Server CDC 捕获表最多只能创建 2 张是硬性限制,但刚好能解决这个问题,在 DDL 发生后创建第二个 CDC 捕获表可以感知到 DDL 对数据的变化

  1. 创建第一个 CDC 捕获表 dbo_test_table_1_CT
  2. 在两次数据插入的中间增加一个新的列
  3. 创建第二个 CDC 捕获表 dbo_test_table_2_CT
  4. 在插入一条新数据

通过上图可看到 dbo_test_table_2_CT 相比 dbo_test_table_1_CT 已经可以感知到新增的列数据

遗憾的是 DDL 发生后到第二个 CDC 捕获表创建出来之前这中间的数据仍然是缺失的

上面的例子如下图所示(灰色的 Event 表示事件或者数据有缺损)

以 DDL 发生的 LSN 为分界点

  • 在 DDL 发生之前 dbo_test_table_1_CT 表中的数据是完全可信的
  • 在 DDL 发生之后由于 dbo_test_table_1_CT 表中并没有新列字段,因此它的数据是残缺的,不能完全信任
  • dbo_test_table_2_CT 是由于在 DDL 发生后才被创建出来,因此相比较 dbo_test_table_1_CT 它的数据是缺失的
  • 此外 dbo_test_table_1_CTdbo_test_table_2_CT 之间还存在一个盲区导致这个 INSERT 事件两个表都不可信

CloudCanal 解决办法是在此基础上将两张表都缺损的位点 反向使用 PK 从源表中补齐 的方式解决这个问题(上图中深灰色部分)

有一个极端情况是在第二张 CDC 捕获表创建过程中发生了新的 DDL ,这会导致新创建的捕获表也不可靠,因此需要重新创建第二个 CDC 捕获表,并且扩大中间需要反查补齐的数据范围(下图中深灰色部分)

CloudCanal 正是基于上述一系列机制才解决了 DDL 事件导致无法获取增量数据的难题

解决难点3:提供专业优化方案

对于硬性限制,CloudCanal 没有正面解决的方案,而是后续提供更多样的方式(如 trigger,定时增量扫描,新版本SQL Server CDC方案 等)进行补充。

软性限制,可通过以下方式优化

  • 通过以下命令中的 retention 参数来设置 CDC 捕获表中的数据存留时间

    exec console.sys.sp_cdc_change_job 
    @job_type = 'cleanup',
    @retention=4320 -- 单位:秒
  • 通过以下命令调整 CDC 处理的最大数据字节

    exec sp_configure 'show advanced options', 1 ;   
    reconfigure;
    exec sp_configure 'max text repl size', -1; -- -1 表示不限制
    reconfigure;

总结

本文简单介绍了 SQL Server CDC 技术,然后基于此能力,CloudCanal 是如何实现稳定的增量 DML + DDL 同步, 并且解决了其中遇到的难题。

支持 GH-OST 和 PT-OSC

· 阅读需 9 分钟
John Li
John Li
Chief Executive Officer

简介

CloudCanal 实现了对 Online DDL 工具如 GH-OST 和 PT-OSC 的支持,保证了对端实时同步源端的 Online DDL 操作。

本文以 MySQL -> MySQL 同步链路使用 GH-OST 为例,介绍 CloudCanal 是如何支持实时同步 GH-OST 产生的 DDL 的。

Online DDL 技术背景

市面上常用的两款MySQL Online DDL 工具分别是 GH-OST 和 PT-OSC,CloudCanal 对他们都做了兼容处理使得用户可以实时同步 Online DDL 工具产生的 DDL 。下面简单介绍下他们的工作流程,以便于读者理解后续章节的内容。

Online DDL 工具 PT-OSC 原理

PT-OSC 是较为常用的 Online DDL 工具,通过触发器来同步增量数据,相较于 MySQL 原生的 Online DDL 性能得到了极大的提高,原理如下:

  • 对源表进行检查
  • 创建一个与源表(origin)结构一致的空表,命名为 _origin_new
  • 根据alter参数修改新表的表结构
  • 在源表中创建三个触发器:Delete / Update / Insert,将源表中的增删改语句同步执行到新表中,同时将源表中的数据以数据块的形式 copy 到新表
  • 将源表(origin)rename为 _origin_old,将 _origin_new rename 为 origin,然后删除旧表(可选)
  • 删除触发器

总结:PT-OSC 是通过创建临时表,并用触发器将增量数据同步到新表,通过当前读和事务来实现增量与全量的有序,不会阻塞读写操作,但运行过程中出现异常,无法从上一个位置继续进行,需要从头开始。

Online DDL 工具 GH-OST 原理

GH-OST 也是一款常用的 Online DDL 工具,采用读取 binlog 日志的方式来同步增量数据,原理如下:

  • 对源表(origin)进行检查
  • 在主/从节点中添加binlog日志监听
  • 创建日志记录表(_origin_ghc)和与源表结构一致的影子表(_origin_gho)
  • 根据alter参数修改影子表的表结构
  • 全量拷贝源表数据同时拷贝源表增量数据到影子表中,并记录日志到日志记录表中
  • 删除日志记录表,将源表改名为 _origin_del, 将影子表改名为 origin,_origin_del 可选删除

总结: GH-OST 的性能与 PT-OSC 相近,相较于PT-OSC 的优点就在于其是不使用触发器的,只异步读取二进制日志,因此修改表定义的负载和正常的业务负载解耦开了,它不需要考虑被修改的表上的并发操作和竞争等,并且相较于 PT-OSC 的中断从头开始,GH-OST 可以从心跳日志中恢复到指定位置。

CloudCanal 技术点

前文中对 Online DDL 工具的原理中我们知道,无论采用哪种 Online DDL 工具,源端都会产生一些临时表的创建和数据写入,如果不做任何兼容处理,这会影响正常的迁移同步链路。

因此为了支持 GH-OST 和 PT-OSC 工具的使用,CloudCanal 在 MySQL 源端做了大量优化,完美的适配并优化了 GH-OST 和 PT-OSC 的 Online DDL 能力

同步临时表数据

GH-OST 和 PT-OSC 工具都有一个共同的特点,其原理都是采用临时表的方式来保证 DDL 与 DML 的并发操作。

CloudCanal 默认的表订阅模式是只订阅原表,不订阅与原表相关的临时表(订阅表即同步该表的 DDL 与 DML 语句),而 CloudCanal 为了满足对 Online DDL 工具的支持,在源数据端配置上新增了 extraDDL 参数来实现对临时表的订阅。

  • extraDDL参数
    • 可选参数:NONE / GHOST / PT
    • 作用:选择 NONE 则不订阅任何临时表,选择 GHOST / PT 则订阅相应的默认临时表

CloudCanal 针对临时表订阅采用的是两种模式:自动订阅临时表模式和自动同步元数据模式

  • 自动订阅临时表:CloudCanal 会自动根据 extraDDL 参数将默认的临时表加入到订阅表集合中,随后读取binlog日志时将不会过滤掉临时表的所有变更事件,保证了对端数据源表结构与数据的最终一致性
  • 自动同步元数据:CloudCanal 会自动过滤临时表,在读取binlog日志时不会执行 Online DDL 的操作,在 Online DDL 执行完毕后发送最新的表结构,期间的 DML 语句也会同步发送到对端,保证对端数据源表结构与数据的最终一致性

由于各数据源对同步数据的消费并不相同,如消息队列只需要解析 Online DDL 后的表结构即可,无需订阅临时表,因此我们需要根据对端数据源的消费模式做出不同的处理。

DDL 解析与转换

不同数据源的 DDL 语句会有所差异,CloudCanal 对不同数据源 DDL 语句的解析和转换做了大量的优化。

  1. 解析:将 DDL 语句解析为操作类型,如 CREATE ,DROP,ALTER 等
  2. 拆分过滤:若 DDL 语句不为单条操作,则拆分为多条 DDL 语句,根据订阅表集合和binlog位点记录过滤重复执行的 DDL 语句与去除无需同步的语句后,重新合成新的 DDL 语句
  3. 转换:将过滤好的 DDL 语句转换为对端数据源的方言

下图演示了CloudCanal对DDL语句的一些处理:

容错机制

当 CloudCanal 在同步 Online DDL 时,任务有可能在两个层面上被中断:Online DDL 工具层面和 CloudCanal任务层面

  • Online DDL 工具中断:由于 PT-OSC 和 GH-OST 的原理不同,Online DDL 过程中断的恢复方案也有所不同

    • PT-OSC:Online DDL 过程中出现异常中断,重新执行 Online DDL 操作会丢弃之前的所有操作,从头开始再次执行
    • GH-OST:Online DDL 过程中出现异常中断,重新执行 Online DDL 操作会读取ghc日志心跳表,从日志中的未完成位点开始继续执行。在此过程中,CloudCanal只需读取binlog日志,照常执行 Online DDL 的所有操作即可保证数据的最终一致性
  • CloudCanal任务中断:由于 CloudCanal 良好的异步消费特性,CloudCanal的任务中断与 Online DDL 的执行并不相关。当 CloudCanal 任务中断后,重启任务会根据位点记录继续执行binlog日志中的事件,保证了数据的最终一致性。

使用示例

前置条件

CREATE TABLE `ghost_test`.`abc` (
`id` int NOT NULL,
`name` varchar(30) DEFAULT NULL,
`cdata` datetime DEFAULT NULL,
`udata` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
  • 登录 CloudCanal 平台 ,添加源端与目标端数据源

任务创建

  • 任务管理 -> 任务创建。
  • 测试连接并选择 目标 数据库。
  • 选择增量同步任务和需要订阅的表与字段,并创建任务
  • 增量任务中,功能列表 -> 参数修改 -> 源数据源配置 -> 参数 extraDDL 设置为 GHOST

创建并且启动任务,当任务正常执行到增量阶段时,此时我们可以利用数据生成工具和Online DDL工具对源端数据库触发一些增量DML变更和DDL变更,然后查看CloudCanal是否能正常实时同步这些DML和DDL事件。

使用 Online DDL 工具修改表结构

  • 首先使用数据生成工具实时随机生成数据,增删改比例为(4:4:3)

  • 在大量写入数据的同时,使用 GH-OST 工具执行 DDL 语句:ALTER TABLE ADD COLUMN aaa VARCHAR(30) NOT NULL AFTER id。在我们的测试例子中,有 DML 语句的同时使用 GH-OST 执行 DDL 语句,源端总计写入14147 条数据和1条DDL。

[root@zjx local] ./gh-ost --debug --user="{数据库用户名}" --password="{数据库密码}" --host="{数据库主机IP}" --port="{数据库端口号}" --database="ghost_test" --table="abc" --initially-drop-ghost-table --initially-drop-old-table --allow-on-master --alter="ADD COLUMN aaa varchar(30) NOT NULL AFTER id" --execute

确认同步结果

CloudCanal会自动完成源端实时DML和DDL事件的同步,在执行完源端事件写入之后,我们确认下同步结果。

  • 更改后的源对端 表结构一致

  • 源对端进行数据校验 数据一致

总结:由上可知,在 CloudCanal 中使用 GH-OST 工具执行 Online DDL 指令,源表完成表结构修改后,CloudCanal 将源表的表结构成功同步到了目标端数据表中。

常见问题

CloudCanal 支持的同步链路

目前 CloudCanal 支持使用 Online DDL 工具的链路为:

  • MySQL -> MySQL
  • MySQL -> PostgreSQL
  • MySQL -> Greenplum
  • MySQL -> Kafka
  • MySQL -> RocketMQ
  • MySQL -> RabbitMQ

不支持同步的 DDL 语句

使用 Online DDL 工具执行的 DDL 语句中不支持 RENAME 原表与临时表的操作,如上述用例中,ALTER 语句若改为 RENAME TABLE ghost_test.abc TO ghost_test.ccc,那么 Online DDL 工具后续的 RENAME TABLE ghost_test.abc TO ghost_test._abc_del, ghost_test._abc_gho TO ghost_test.abc 操作就会失败,致使 Online DDL 操作失败。

总结

本文主要介绍了 Online DDL 工具的使用并展示了 CloudCanal 对 Online DDL 工具的实时同步能力,得益于 GH-OST、PT-OSC 优秀的表结构修改性能和 CloudCanal 强大的同步能力,基本能满足企业在日常执行 DDL 的业务中,数据表的 DML 执行和数据同步性能要求

深入浅出地理数据(GIS)迁移同步

· 阅读需 15 分钟
Barry
Chief Technology Officer

背景知识

什么是地理信息数据

地理信息数据的定义主要来自于我们熟知的星球——地球。我们知道地球表面是一个凸凹不平的表面,是一个近似的椭球体。以海平面为参照已知最高点和最低点之间有接近 2 万米的差距。

  • 珠穆朗玛峰,8848.86米含冰层(人民日报:2020年12月8日)
  • 马里亚纳海沟,相对海平面深10909米(人民日报:2020年11月30日)

即便是海平面也会在月球潮汐引力的作用下变化着,更不要提气候变化导致的海平面升高。因此要想找到一个确切的数学模型来表示地球还是挺困难的一件事。

于是人们以北极南极为两个定点,将地球按照这个轴线进行旋转。地球在这个旋转形态的下就会呈现一个椭球体的形态,这个就是理想的地球椭球体。这个椭球体就可以利用数学模型来进行表示。

正是基于这样一个共识,在 1975 年国际大地测量与地球物理联合会推荐下地球椭球体的模型数据被推荐为:半长径 6378140 米,半短径 6356755 米,扁率 1∶298.257,后续该数值有一些修正。

基于这些精准的测量数据,我们可以通过数学表示来定义地球上所有的点,从而利用现代化的定位技术我们可以精确定位地球上所有的位置。

定位技术

在地球上要想知道我们精确位置可以使用导航软件,导航软件的正常工作需要依赖全球定位系统。目前世界上共有四大导航系统,分别是

  • 中国的 北斗

  • 美国的 GPS

  • 欧盟的 伽利略

  • 俄罗斯的 格洛纳斯

这些定位系统最主要的部分是人造卫星,它们按照固定的规律围绕地球运转,其中有一些是运行在圆形的地球同步轨道上。

由于每个卫星和我们的距离不同,因此它们同一时刻发送的信标会以微小的时间间隔先后抵达我们的设备上。这样我们就有了带有延迟的信标信号,每一个延迟是可以被看作是一个距离。

我们事先知道每一个卫星的确切位置,再加上这些距离信息。当我们得到最少 3个信号之后就可以利用著名的三角定位法得到我们的准确位置,这也是所有卫星定位技术使用的核心原理。

空间数据

现有空间数据库标准主要有如下两套,两套标准之间大体是相互兼容的。

  • Simple Feature Access SQL,简称 SFA SQL:SFA SQL是 开放地理空间信息联盟(Open Geospatial Consortium,简称 OGC)制定的标准。

  • SQL Multimedia Part3: Spatial,简称 SQL/MM:SQL/MM 是 国际标准化组织(International Standard Organization,简称 ISO)制定的标准。

通过空间数据的描述我们可以定义一个具体的几何体。在这两种标准中公共的部分中都定义了下面 3 组共 6 个基础类型,这些是经常用到的类型。

  • 点、多个点
  • 线、多个线
  • 多边形、多个多边形

为了方便存储和使用这些数据 OGC 组织通过 OpenGIS 规范定了两种具体格式

  • Well-Known Text (WKT) format
  • Well-Known Binary (WKB) format

WKB/WKT 都只是通过标记语言描述点、线、面 的几何体数据,当用于几何计算时一般不需要坐标系。但是当数据需要展示在地图上时则需要将其原始的空间数据投射到大地坐标系上(这个过程称为投影)才可以得到这个几何图形具体的地理坐标。

空间引用识别号(SRID)

要将几何图形投影到坐标系,必须需要使用SRID。SRID可以理解为唯一标识了将某个几何体空间数据映射成某个具体坐标系中的方式。

当SRID为0或者不使用SRID时,表示一个几何图形实例没有被放到任何一个坐标系中,我们无法定位其位置。例如通过长宽高的具体值我们可以知道一个正方体的形状,但是我们没法知道他的具体坐标。

不同SRID值代表了将几何体映射到坐标系中的不同方式。几何体本身的空间数据结合SRID就可以具体定位这个几何体在坐标系中的位置。

下图简单演示了有无SRID得差异。像欧洲石油测绘组 (EPSG) 定义的 SRID是根据地球地理信息构建的坐标系,几何图形根据几何体空间数据以及EPSG标准的SRID值可以转成真实的地理坐标。

目前有多种公认的标准 SRID,例如欧洲石油测绘组 (EPSG) 定义的 SRID。不同数据库对于不同SRID标准的适配性也不同。

某些数据库和空间类型(如 PostgreSQL 中的 PostGIS 几何和地理或 Microsoft SQL Server 中的地理类型)使用预定义的 EPSG 代码子集,只可使用具有这些 SRID 的空间参考。

如今编制 SIRD 的工作已经转交给了国际石油和天然气生产商协会(OGP) 的手中,要想了解更多的EPSG信息,可以访问 https://epsg.io/

常见SRID标准与地理坐标系

在中国常用的坐标系有下面四个

  • WGS84:美国 GPS 系统上使用的坐标系。
  • GCJ02:由中国国家测绘局制定的地理坐标系统。
  • BD09:百度地图所使用的坐标系,它是建立在 GCJ02 坐标系之上。
  • CGCS2000:中国北斗系统所使用的坐标系。

大地坐标系与地图绘制

地图绘制的基本步骤

绘制地图构建大地坐标系主要会采用以下步骤:

  1. 首先会选择一个基准点,所有的地形数据都是基于这个基准点的进行绘制。而这个点也正是位于地球椭球体上的一个点。

  2. 地球椭球体可以充当画布,测绘员则可以在画布上勾勒出具体的街道和地形信息。从而形成最终的地图数据供我们使用。

  3. 基于定位的点和地图的基准点的之间的偏差就可以完成整个定位到地图的转换这个过程就是坐标系转换。当然实际的过程要更为复杂一些,甚至会有多次偏差修正。

存储地理信息

目前主流关系型数据库对地理信息基本都都有支持,其中最常用的类型便是 geometry 类型。在 Oracle 数据库中对应为 sdo_geometry 类型。

还有其它的几何类型,例如:PointPolygonMultiPointMultiPolygon 等等,介于篇幅的原因本文内容只针对 geometry类型。

有兴趣深入了解的朋友可以根据下方表格自行深入研究,本文不做过多展开。

数据库几何类型
MySQLPOINT、LINESTRING、POLYGON、MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、
GEOMETRY、GEOMETRYCOLLECTION
PostgreSQLPOINT、LINE、LSEG、BOX、PATH、POLYGON、CIRCLE、GEOMETRY
OracleSDO_GEOMETRY、SDO_TOPO_GEOMETRY、SDO_GEORASTER
SqlServerGEOMETRY、GEOGRAPHY

不同的数据库由于存储和查询引擎的不同,针对地理信息的存储会有一些差异。这些差异主要是因为单纯的 WKB 并不能满足实际需求,最直接的问题就是 WKB 只考虑的几何图形的空间数据存储,但是并未涉及大地坐标系相关的信息。

比如在 MySQL 中地理信息数据将会在 WKB 数据前额外增加 4 个字节用于存放其对应的 SRID。而 PostgreSQL 用了更加高级的 EWKB 格式作为地理信息数据的存储格式。

因此如果想要以二进制方式直接从数据库中获取地理信息数据,了解正确的获取方式十分必要。

地理信息数据应用的问题

我们会从一个具体案例来和大家探讨地理信息数据应用中会遇到的实际问题。我们这个地理数据应用案例如下:

如何知道地球上一块土地在一段时间内的使用情况?

为了达成这个目的,我们将会不得不面临如下的一些挑战:

数据量大

首先土地的使用是随着时间变化而变化的,比如:

  • 在一些时间内这些用地可能是耕地,另外一些时间可能是用作林地。

  • 随着时间推移一块土地可能会被切割成个地块,或者合并成一个更大的地块。

因此每年获取的地图数据都只是当年最新的情况,地块数据也是不停地变化的。

基于这样一个情况,若想要知道一个时间跨度下的地块变化。通常会涵盖不同时间的地图数据。若地图数据是 1G 大小,如果要计算 10 年的变化就需要处理 10G 的历史地图数据。

计算量大

对于地图数据中还会含有很多其它结构化数据,比如:小区、门牌号、餐馆名称,地块通途以及交通道路等等信息。因此在基于业务查询需要会先进行业务维度上的数据查询和筛选。

写过业务逻辑的朋友都知道,复杂的业务查询很可能会涉及到几张表的联查操作。在加上我们还需要通过 GIS 函数进行几何图形的交并计算。这就会引发下面两个问题

  • 大量的地理的几何信息、标注信息引发出大表的 Join 性能问题。

  • 由于GIS的函数计算引发的大量计算。

没有万能的数据库

现在主流的对地理信息存储比较友好的数据库主要是PostgreSQL、Oracle和SQLServer。像PostgreSQL对地理信息数据处理的生态工具也比较友好,例如:

  • PostgreSQL 对 GeoServer、MapServer、ArcGISServer 几个地图服务中间件的支持性比较好。
  • PostgreSQL 对 PostGIS 的支持兼容性要比 Greenplum 好

这些传统数据库并不能解决所有问题,尤其是面临千万级别的 GIS 表时,表的 Join 查询又会面临严重的问题。

幸运的是,近几年新型和强力的OLAP分析型数据库不断出现,地理信息数据的处理和分析可以结合这些新型分析引擎大大提升地理信息数据处理的效率。

高效处理地理信息数据的现代化数据栈

以下现代化数据栈的方案来自于CloudCanal用户的一个真实案例。该用户原有方案是基于PostgreSQL进行地理信息数据的查询和处理。

通过CloudCanal数据互通,采用如下现代化的数据栈,轻松整合了ClickHouse强大的分析能力和ElasticSearch的强大全文索引能力来处理地理信息数据,大大提升了地理信息数据处理的效率。

数据栈架构图

以上架构图展示了整个地理信息数据的流向以及处理过程:

  1. PostgreSQL对地理信息存储和处理比较友好,业务应用先将产生的地理信息数据全部写入到PostgreSQL中

  2. 利用CloudCanal在异构数据源之间迁移和同步地理信息数据,自动化地转化地理信息数据写入新型的数据源中

  3. 利用ClickHouse强大的分析能力来高效处理地理信息数据

    1. 海量地理信息数据的聚合、join分析操作

    2. 应用利用ClickHouse强大的分析能力先进行数据初筛,生成数据量较小的有效数据,直接对数据规模较小的地理信息数据使用JTS工具进行二次几何函数计算然后生成最终处理结果

  4. 利用ElasticSearch强大的全文索引能力,应用可以直接对ElasticSearch中存储的地理信息数据进行全文检索

可以看到采用CloudCanal以后得现代化数据栈处理地理信息数据具有如下好处:

  • 可以应对复杂的业务查询需要,针对业务选用不同的新型数据库提升效率。

  • 应用可以直接使用分析引擎过滤出来的较小数据规模的地理信息数据进行几何函数计算,大大提升效率。

CloudCanal中对于地理信息数据友好兼容

表结构迁移

在使用 PostgreSQL 作为主库,ClickHouse 作为分析库的时候。第一个问题就是 ClickHouse 的建表,在没有 CloudCanal 工具,建表比较痛苦,使用 CloudCanal ,这个过程就会相当便利。

  • PostgreSQL 没有类似 MySQL show create table 的语句可以方便的获取到原始建表语句让我们参照,因此需要一张表一张表的去创建。

  • ClickHouse 的表字端类型和 PostgreSQL 的字端类型并不一致,还需要了解它们做针对的映射和转换。

即便是在 PostgreSQL 和 PostgreSQL 之间进行数据同步,还需要考虑一些问题

  • 带有 SRID 的 PostgreSQL 表结构迁移

这些问题通过使用 CloudCanal 解决,它会自动识别表的字段类型并且映射到适合的列上,这样就省了不少学习了解新数据库的时间。

同样 CloudCanal 就像 PostgreSQL 一样对 GIS 特性支持比较完整,它能够准确处理带有 SRID 的 PostgreSQL 表结构。如下表。

CREATE TABLE "city"
(
"ogc_fid" int4 NOT NULL,
"mssm" varchar(16),
"bz" varchar(16),
"provincen" varchar(50),
"provincec" varchar(50),
"cityn" varchar(50),
"cityc" varchar(50),
"shape_leng" float4,
"shape_area" float4,
"geom" geometry(geometry,4490) -- 带有 SRID 的列
);

数据迁移

CloudCanal支持将用户源端数据库中的地理信息相关数据完整迁移到对端异构数据源,并且支持断点续传。

在地理信息数据的迁移上,CloudCanal做了不少工作。当源端数据库是 PostgreSQL 时。全量数据同步过程会识别到表上的 SRID 信息,并将 PostgreSQL 使用 EWKB 格式转换为标准的 WKT 连同 SRID 一同作为最终数据。

  • 当对端是 ClickHouse 的时候我们可以得到完整的 GIS 地理信息数据以及对应的坐标系 SRID,在程序中可以进一步处理。

  • 当对端是 PostgreSQL 时也可以完整的将地理信息和坐标系同步到对端。

自定义处理

在地理信息数据从源端数据库迁移/同步到对端数据库过程中,通过 CloudCanal 自定义代码功能可以做一些非常灵活的加工操作。

用户可以自己实现自定义代码,在数据同步过程中针对每一条数据做一些额外的处理。比如:

  • 在处理 GIS 的应用中经常会用到求外切,得到几何图形的最大矩形区域。然后将这个矩形区域存储在一个新的字段中

  • 求 GIS 数据几何图形的中心点

  • 提前裁剪数据,将清洗好、裁剪好的规整数据写入对端新型数据库。

长周期的实时地理信息数据同步

CloudCanal不仅支持历史数据的迁移同时还支持异构数据源之间的实时数据同步。实时的地理信息数据同步能够加强企业在某些业务领域的竞争力。

在实时同步时,用户最关心的自然是长周期实时同步的稳定性。

在实际情况中为了保障业务运行中对于实时数据同步的稳定性 CloudCanal 采用了多种方式来实现。

  • 完全分布式:核心组件均支持分布式部署,避免单点故障

  • 容灾自动恢复:如果运行实时同步任务的机器Crash,CloudCanal会自动迁移这台机器上的实时同步任务到别的可用的机器继续实时化的同步

  • 实时同步断点续传:CloudCanal针对各种数据库源端类型都有设计专门的位点管理。当因故障产生任务重启,任务会在上一次中断的地方继续开始同步,避免数据丢失。

总结

在本文最初我们比较简略的介绍了地理信息数据相关的背景知识,文章后半段我们探讨了如何利用现代化的数据栈高效处理地理信息数据。

参考资料

  • 北斗卫星导航系统公开服务性能规范1.0 版
  • 习近平同尼泊尔总统班达里互致信函 共同宣布珠穆朗玛峰高程
  • “奋斗者”号全海深载人潜水器顺利完成万米深潜试验
  • 北斗卫星导航系统 公开服务性能规范
  • 高精度地图(一)——地理坐标系
  • The Home of Location Technology Innovation and Collaboration
  • MYSQL 8.0 中存储 GIS 数据的正确姿势

CloudCanal 和 Canal 区别

· 阅读需 3 分钟
John Li
John Li
Chief Executive Officer

前言

近期 CloudCanal 和 Canal 是什么关系的疑惑,这边统一回答下。

研发团队

CloudCanal 核心团队成员来自阿里巴巴中间件和数据库团队, 长期从事分布式数据库、数据库中间件、应用中间件工作,包括阿里云分布式数据库中间件产品 DRDS、内部核心系统数据同步工具精卫、阿里云数据湖产品 DLA 、开源数据网关 Hasor 等产品负责人和核心研发 。

CloudCanal 命名

CloudCanal 取名初衷在于其原始意义:云管道。公司使命是做云时代的数据管理,产品名字高度匹配。和 Canal 名字关联性在于我们使用了一部分 Canal 的 binlog 解析,可以认为是一个全新的产品。

代码

CloudCanal 和 Canal 代码有什么区别

CloudCanal 在 MySQL binlog 解析使用了 Canal 部分代码,其他均为自主研发,并且对 Canal 部分代码进行了大量重构,修复诸多问题并优化性能。Canal 在 CloudCanal 中的位置,可以用以下图片简单表示,可见 Canal 代码在 CloudCanal 产品中只占很小一部分。

d840d344-a9e3-420f-af15-a4ae91393c50-image.png

CloudCanal 和 Canal 功能差异

功能CloudCanalCanal
可视化任务创建
可视化参数配置
任务生命周期管理全自动流转
数据库支撑度高:10种源端/22种对端(阿里云加自建)中:源端以 MySQL 为主,对端支持RDB、kudu、hbase和es
结构迁移支持不支持
全量迁移支持不支持
增量同步支持支持
数据校验支持不支持
数据订正支持不支持
数据条件过滤支持不支持
同步异常处理支持不支持
列裁剪可视化配置blackField参数文件配置
列映射可视化配置不支持
自定义虚拟列支持不支持
限流支持不支持
可视化监控支持不支持
告警(钉钉、短信)支持不支持
位点回溯、重置支持参数文件设置
白屏化日志支持不支持
异常大盘支持不支持
阿里云数据源支持API级别集成不支持
数据源管理能力支持不支持
机器管理能力支持不支持
操作审计支持不支持

写在最后

CloudCanal 相比 Canal 具备更加丰富的数据源支持,产品化、自动化程度更高,也具备免费社区版和配套商业服务的商业版本,Canal为开源产品,社区更加强大和开放。

Oracle 数据迁移同步优化与思考

· 阅读需 15 分钟
John Li
John Li
Chief Executive Officer

为什么我们要重构 Oracle 源端数据同步?

CloudCanal 早期版本即支持了 Oracle 数据库,围绕结构迁移全量迁移增量同步三个核心步骤,构建了以 Oracle 数据库为源端的实时数据体系。

但之前的版本,也存在着不少问题,功能、性能、对数据库权限的挑战等方面都有所涉及,是 CloudCanal 产品的一个痛点,看着 MySQL 源端在线数据体系不断狂奔,不免有点落寞。

再者,市场的需求层出不穷,“CloudCanal 能否把 Oracle 数据同步到 Kafka?”CloudCanal 能否把 Oracle 数据同步到 ElasticSearch ?”我们在做业务重构,你们能做 Oracle 到 Oracle 的数据同步么?”...

为此,我们下定决心,决定在春夏之交,给 CloudCanal Oracle 源端动一场大手术。

如何优化?

两种实现方式的选择

最有力的改变往往来自于某一个特定方向的深入挖掘。

对于老版本 Oracle 源端增量实现的物化视图方式(类trigger)和 LogMiner (Redo日志解析) , 我们选择深度优化 LogMiner,理由有三

  • LogMiner为 Oracle 官方提供 Redo 日志解析,方式相对可靠
  • CloudCanal 实现的 MySQL / PostgreSQL / MongoDB 源端增量都偏向于操作日志解析,风格一致,组件可共用性概率高
  • 从业界的调研来看,LogMiner在落地 Oracle 严格 CDC 场景下,表现可圈可点

确定我们核心追求的效果

可持续稳定运行成为我们优化的主要目标,这句话的含义可能并非字面所理解,实际包含以下几个问题的解决

  • 能否在突发压力下(5000 条数据/秒)稳定运行?
  • 能否在超级大事务下( >1000万条数据数据订正)稳定运行?
  • 能否不中断任务平滑新增表、减少表
  • 能否自动处理源端常用 DDL 同步(加列/改列/减列)?
  • 能否重复消费一段时间的增量数据(回拉位点)?

我们做了哪些事情?

确定了优化方向和目标,接下来事情就相对好办,我们从 内核核心逻辑优化产品层面优化 两个方面进行改进。

内核核心逻辑优化

ADD_FILE 模式和 CONTINUOUS_MINE 模式支持

Oracle LogMiner本身并不是专门为实时 CDC 所设计,商业方向由其商业产品 GoldenGate 扛旗,免费工具层面又有 Oracle CDC 专用组件,但是 LogMiner主要胜在其被许多前辈所验证,古老且稳定,所以被选择演化为 Oracle 主要的实时同步组件也并不奇怪。

LogMiner最原始的使用方式包含以下几个步骤

  • DBMS_LOGMNR_D.BUILD (构建解析的字典,可选)
  • DBMS_LOGMNR.ADD_LOGFILE (添加需要解析的 redo 日志)
  • DBMS_LOGMNR.START_LOGMNR (开始解析增量日志)
  • V$LOGMNR_CONTENTS (从此视图中查询解析的增量日志)
  • DBMS_LOGMNR.END_LOGMNR (结束解析)

事实上,这几个命令通过改变使用组合,增删具体的参数,即可达成增量日志效果,通用的模式即 ADD_FILE 模式,CloudCanal 对这种模式做了大量优化与验证,构成其 Oracle 源端增量同步的基本盘

但是上述步骤中,DBMS_LOGMNR.ADD_LOGFILE 因为 Oracle 的日志结构构成,对于细节处理要求较高,如果没处理好,在某些场景下,容易丢失数据

Oracle Redo日志如下结构

- online redo log (在线日志)
- redo04
- redo05
- redo06
- archieved redo log (归档日志)
- redo log with dictionary start
- redo log with dictionary end
- redo log with both dictionary start and end
- redo log without dirctionary

其中在线日志有2+个组(完全镜像),每一个组里面 2/3 个文件进行轮换,在线文件会归档到归档日志,所有文件通过递增 sequence 维持顺序。

请问怎么样往 LogMiner添加文件不会丢数据也不会重复解析日志?为了简化这个问题,Oracle 为 LogMiner推出了 CONTINUOUS_MINE ,也就是不需要指定日志文件,自动帮你添加,不断吐出新的变更。

当我们看到这个能力的时候,觉得 Oracle 挺厚道的,但是我们很快发现了不厚道的事情,Oracle 12.2 deprecated 此项特性,19c 直接去掉了这项能力 ...但是我们还是支持了这个能力,在 11 / 12 部分版本能够选择使用该项能力。 截屏2022-07-29 15.28.39.png

更加实时

两种模式的支持过程中,我们大大 缩小老版本解析 redo 日志的范围,通过位点管理的重构,杜绝可能的重复添加已解析过日志文件,另外为了方便运维,DBA 同学可选择 CloudCanal 定时或相隔时间段构建字典的能力。

Read Commited 级别可见性

关系型数据库 Redo 文件包含几乎所有的操作,所以也隐含了数据库对外可见性在日志中,LogMiner支持只吐出已提交(commited)的日志,但是我们并没有选择这种方式,原因有四

  • V$LOGMNR_CONTENTS 是一个视图,会话级别,一个大型数据变更,选择 commited 数据消费将会影响 Oracle 稳定性
  • 一个大型的数据变更,Oracle 等待 commit 再消费会导致大的数据延迟
  • CloudCanal 对于超级大事务有刷盘机制,LogMiner边吐日志边处理,安全且高效
  • 此种机制不阻塞在超级大事务之间并发执行的小事务提交

当日志不断从 LogMiner结果视图查询出来时,CloudCanal 的内存结构完美重现了一遍 Oracle Read Commit 级别的操作。

大事务支持

CloudCanal 新版本对于源端大事务做了充分的支持,当单个事务变更数小于固定值(默认 512 个),则全内存操作,一旦超过此数值,即开始刷盘,直到 commit 或 rollback 操作发生,进行后续的消费或者丢弃。

持久化变更操作到硬盘时,我们采用了kyro 序列化工具提升压缩比和 cpu 编解码效率,为了让数据序列化/反序列化可控,我们采用了最可靠的自定义序列化器方式,防止 kryo 通过反射制造各种惨案,将序列化类型限定在 java 最基础的几种类型上,让这块代码坚若磐石。

可选择的字典(ONLINE or IN_REDO)

LogMiner分析的 Redo 时,必须包含日志的字典信息,否则解析出来的数据相当于乱码,无法识别,导致丢数据。可选择的两种字典类型,存在以下区别。

  • ONLINE : 即当前字典,无法配置 DDL 参数 DDL_DICT_TRACKING进行历史日志分析(比如做了 DDL 在表中间加了一个列,DDL 之后的变更可以解析,但是之前的变更可能解析失败)
  • IN_REDO :即以归档日志中存在的字典作为基准,配合 DDL_DICT_TRACKING构建演进的字典,即可做历史日志的解析(无论发生多少个 DDL,每一个事件都能获取到精确的元信息)

CloudCanal 新版本默认采用 IN_REDO 模式的元数据(依赖字典数据构建),但是也提供了 ONLINE 形式的字典,让增量任务启动更加顺畅(无前置构建字典必要) 截屏2022-07-29 15.27.12.png

更好的 redo 解析器

LogMiner 解析日志生成的核心数据 redo / undo SQL ,如果需要得到结构化数据,必须使用 SQL 解析,方案一般有三种

  • Antlr 解析(自定义文法)
  • 纯字符串解析
  • 其他成熟工具解析(如阿里 Druid)

是的,因为老版本代码这部分有参考某著名开源产品 , 所以我们使用的是纯字符串解析,爽快没多久,惨案便发生,对于 redo sql 中,业务数据值的千变万化,手工解析无疑是一个定时炸弹,所以我们决定使用 Druid 的 SQL 解析器,原因有三

  • 我们其他功能有使用 Druid 和他的 SQL 解析器,摸透了她的特点
  • 能找到作者,而且作者人很 nice
  • 即使最后我们需要自己维护,难度层面完全可以接受

常见 DDL 同步支持

对于 DDL 同步,特别是 Oracle 数据库源端增量同步 DDL,国内有一个著名通信公司同事和我们说,如果你们支持,我们就买,因为太烦太痛。

数据同步工具对于 DDL 事件的处理,实际上分为两个部分

  • 更新表元数据,以解析新事件
  • 同步到对端,让源和对端结构保持一致

对于第一项,是一定要做的事情,否则同步可能中断以及解析增量数据可能出错。对于第二项,我们的建议是通过统一的平台来做(比如我们的 CloudDM ),而这个并不是我们不想或不能,而是因为历史/技术的局限性,对端数据库无法做到快速的 DDL 变更,导致同步延迟或加大同步链路稳定性问题(长时间延迟可能出现各种不确定事件)。 不过应最终客户的需求,我们在 CloudCanal 新版本中做到了这两项。其中对端同步到 MySQL 我们支持

  • ALTER TABLE xxx ADD xxx ;
  • ALTER TABLE xxx DROP COLUMN xxx;
  • ALTER TABLE xxx MODIFY xxx;

搭好了舞台,开了一个好头,后续不断完善。

多版本 schema 以支持位点回拉

对于关系型数据库同步工具而言,增量数据本身往往和元数据分离,也就是消费到的增量数据和即时从数据库里面获取的元数据不一定匹配(两个时间点之间有DDL)。故维持一个多版本的元数据以应对增量数据解析是刚需。

CloudCanal 以每天的 schema dump 为基准,辅以到当前位点的 DDL 语句列表,可构建出任何时间点的元数据(实际上是更加精确的 scn 位点)。单个 DDL 前后的数据变更事件,能够精确匹配到相对应的元数据,进行解析。

所以 CloudCanal 才有可能在此版本产品上提供了回拉位点重复消费一段时间增量数据的能力。 截屏2022-07-29 15.27.34.png

更加高效的数据结构

CloudCanal 新版本参考 MySQL 源端增量,将多个已提交事务批量交付给写入端进行写入,而针对大事务,提交后按照参数进行拆分,一边从硬盘上流式读取数据,一边写入对端,安全又高效。

更加合理的存取结构,将数据同步性能由原来的 几百 rps 提升到5000+ rps ,满足业务突发流量的实时同步需求。

产品层面优化

支持全量数据校验

同步工具如果没有数据校验能力,往往会存在丢失数据的风险。显性层面表现为是否有数据校验功能,而隐性层面表现为是否做过多样化数据场景构建和数据校验

  • 测试的时候有多少张表?
  • 单表并发多少?
  • 单事务操作数多少?
  • 操作种类和比例多少?
  • 跑了多长时间?
  • 有没有暴力 kill ?
  • 极限硬件测试(资源有限,压力大)?

CloudCanal 新版本对于 Oracle 源端链路补足了此项能力,几百万、上千万条数据中,一条遗漏、一个字段不一致都逃不过数据校验。在交付用户/客户使用前,我们已经做了这些事情。 截屏2022-07-29 17.01.08.png

#支持 Oracle 源端的任务编辑

业务方a 给 DBA 提了一个需求,希望把数据库 A 中表 1、2、3 配置同步到 Kafka 中,DBA 同学顺利完成任务。过了一些天,业务方b 又给 DBA 提了另外一个需求,将数据库 A 中表 4、5、6 配置同步到 Kafka 中。这个时候,DBA 有两种选择

  • 编辑下业务方 a 的任务,加4、5、6表进去,历史数据怎么办?
  • 新开一个任务,占新机器资源、占新数据连接、不断增加的运维成本?

CloudCanal 提供了平滑编辑订阅的能力,如新增表,则生成子任务,可选择做全量迁移,待增量追上自动合并到主任务一起同步。 截屏2022-07-29 17.00.48.png

支持 Oracle 源端心跳任务

当 Oracle 一段时间完全没有变更,如何确定是任务真的延迟还是没有流量?CloudCanal 新版本参考 MySQL 源端,通过参数配置,打开心跳开关,配置好变更语句和执行间隔,即可自动进行定时变更。准确识别延迟是因为下游不行还是 Oracle 没量。 截屏2022-07-29 15.28.19.png

更加明晰的监控指标

新版本的 CloudCanal 对于 Oracle 源端新增了两个监控指标,V$LOGMNR_CONTENTS 查询速率能准确观察 LogMiner 解析效率,内存中未提交事务数能简明判断后端消费和解析的压力,某些情况下还能精确判定 LogMiner是否吐完数据。 截屏2022-07-29 17.00.23.png

缩小的数据库权限要求

CloudCanal 对 Oracle 数据库的高权限要求,主要来自两个面向 DBA 的操作,自动构建字典自动切换归档日志,这两个操作初心比较简单,让用户使用更加自动化和便利,但是问题也比较明显,对数据库运维标准严苛的客户来说,这些操作在某些情况下是不可接受的。

所以新版本 CloudCanal ,通过参数配置,支持了关闭自动字典构建能力(默认打开)关闭自动切换归档日志能力(默认关闭)。用户在关闭这些功能时,能够知道必须辅以哪些运维操作,才能让 CloudCanal 正常运行。

其他的功能和修复

通用能力方面,我们此次打开了创建 Oracle 源端任务 支持数据过滤条件的功能,但是语法依然仅限于SQL92 的有限语法范围内,和 MySQL 等其他源端数据源共用一套数据过滤系统。

自定义代码能力对于业务重构、新老系统替换是神器,新版本 CloudCanal 将这个能力打开,它依然和 MySQL 作为源端、PostgreSQL 作为源端,保持能力的一致性,数据过滤、打宽表、字段值变换、操作变化一样不少。

BUG 修复层面,新版本修复了 Oracle 远端全量迁移进度不准问题结构迁移类型映射不准确问题

“术后” 效果如何?

“术后”效果,我们需要回答文章开始之时提出的一些问题。

对于能否在突发压力下(5000 条数据/秒)稳定运行?我们通过 高效的数据结构可调整内存参数阈值优化,基本达到目标(还有提升空间)。

对于能否在超级大事务下( >1000万条数据数据订正)稳定运行?我们通过 非commit数据接收模式大事务支持边获取边写入 三个方法解决问题。

对于能否不中断任务平滑新增表、减少表?我们通过支持 编辑订阅达到目标。

对于能否自动处理源端常用 DDL 同步(加列/改列/减列)?我们通过 多版本schema管理 ,DDL转换与同步两个方法结合解决。

对于能否重复消费一段时间的增量数据(回拉位点)?我们通过支持多版本 schema 管理页面位点重溯功能解决。

我们还将会围绕 Oracle 做些什么?

更多的对端数据源

目前 CloudCanal 源端为 Oracle , 则对端支持 PostgreSQLGreenplumMySQLTiDBOracleKuduStarRocksOceanBaseKafka 数据源,我们在期待解决这些链路可能存在的问题同时,也希望支持更多对 Oracle 在线数据生态有益的对端数据源,比如 ElasticSearchClickHouseMongoDB

探索和其他数据源(如 MySQL)的双向同步可能性

Oracle 是否存在双向同步的可能性,对于很多业务来说,具有很强的实用性,我们希望能够探索出一条成熟类似 MySQL<->MySQL 之间双向同步的方案。Oracle <-> MySQL(Oracle) 双向同步,我们相信对一些用户来说会比较有用。

物化视图(trigger方式)优化

CloudCanal 目前另外一种 Oracle 增量方案-物化视图,是一种权限要求低版本覆盖度好的解决方案,在此次优化中,我们并没有把它列入优化能力点,在后续的一些项目中,我们希望能够将此方案也能够优化好,具有不错的场景适用性。

问题修复

问题修复是我们一直要做的工作,也仰仗各位用户/客户广泛传播使用反馈。沉淀到我们的社区论坛/issue中,我们将会一轮一轮优化,将产品推向极致。

总结

本文主要介绍了我们近段时间对于 Oracle 数据迁移同步的优化,通过这个优化,CloudCanal 具备了相对稳态的 Oracle 数据迁移同步能力,围绕 Oracle 构建数据生态也成为可能,给用户更加广泛应用数据带去助力。

CloudCanal 产品化之道

· 阅读需 7 分钟
Barry
Chief Technology Officer

前言

CloudCanal 是一款由ClouGence公司发行的集结构迁移、数据全量迁移/校验/订正、增量实时同步为一体的数据迁移同步平台。产品包含完整的产品化能力,助力企业打破数据孤岛、完成数据互融互通,从而更好的使用数据。CloudCanal社区版为免费版本,我们会持续地对其维护,请大家放心下载使用。如有兴趣使用请参考文章底部相关资料。

数据同步产品的透明化、可视化运维

数据同步产品是企业的基础设施产品,其透明化、可视化程度与产品的运维、使用效率息息相关。

透明化

透明化指产品内部本身对于用户来说不完全是一个黑盒子,产品内部核心构件以产品化的形式向用户透明,使得用户可以介入内部构件的管理,提供更加精细化的产品控制。

对于数据同步这类基础设施产品,透明化会显得更为重要。数据同步产品由于用户的数据源、数据负载、数据处理需求、机器环境等差异,用户在实际使用、运维中往往需要有对产品更强的干预能力,从而更好的满足自身的场景需求。在数据同步领域,这类干预诉求主要体现在如下几个方面:

  • 源、目标核心组件透明化:用户能够对源端的读取器和对端的写入器有更加精细的控制。例如对于源端可以配置限流、批大小、解析线程数等。
  • 内部组件异常透明化:在私有部署的情况下,数据同步产品的数据源、机器等等都是用户添加的。场景本身的复杂性,不可避免的导致一些由于使用、配置不当而产生的异常。内部组件异常透明化,可以使得用户更加准确、及时的发现问题、解决问题。例如数据同步过程中,数据源突然下线,通过透明化的日志即可看到数据源Connection refused异常,这样,可以快速将问题原因锁定在数据源无法访问这点上。
  • 运行时信息透明化:丰富的运行时信息能够使得出现问题时,提供更多诊断信息,快速定为问题原因。

可视化运维

可视化运维主要体现在产品功能各个维度的可视化成熟度。更高的可视化程度,会带来更好的易用性和产品体验。

CloudCanal透明化、可视化运维

核心组件透明可视化

CloudCanal核心组件主要包含:

  • 控制台(Console): 管控进程,负责产品化能力
  • Sidecar组件: 机器保姆进程,负责task和console之间信息转发以及task的可用性保障
  • 任务内核(Task): 具体迁移、同步任务的执行

其中针对Console组件,其内部还包含以下组件:

  • 异步任务工作流:数据同步任务的创建过程比较复杂,CloudCanal通过异步工作流来完成。
  • 状态机:状态机主要负责任务状态的切换,主要是结构迁移、全量、增量之间的阶段切换

在CloudCanal中,这些核心组件对用户都是透明的,用户可以通过可视化的界面对这些内部组件进行精细化的控制。 2919b29a-cff1-4a20-bffa-37df4056989d-image.png

Sidecar

在机器管理页面可以对Sidecar组件进行控制和检查,包含:

  • 生命周期管理
  • 远程日志查看
  • 详细机器监控(点击圆盘可以进入详细)

e5f11662-9607-42bc-b6e9-3bb07f12a22b-image.png

Console

异步任务工作流

数据同步产品中任务创建是个复杂的流程,往往设计多个子任务。CloudCanal的console内置的异步任务工作流会按顺序执行子任务。针对失败的子任务,我们可以看到具体失败的步骤,以及错误信息,便于运维同学定位问题。 138c8ba7-f494-4fc7-86d6-ca3630641fa8-image.png 6a1d90f8-2125-46ca-aa79-193c11378591-image.png

状态机

每个任务都有其关联的状态机,负责任务的阶段流转。状态的流转由条件触发器触发。 e16fa316-cf69-48c7-b0c1-bd2d17428424-image.png c5510305-3c92-452c-8ff7-4a16edba18ee-image.png

Task

任务详情

任务列表页提供了任务的列表信息和基本的生命周期控制能力以及进度查看。 bda0e5dc-698d-41f7-b260-791429684c9f-image.png

任务详情页面提供了任务完整的详情信息,包括:

  • 生命周期控制
  • 订阅关系查看(库表映射)
  • 源端、目标端数据源详细信息
  • 各阶段同步细节
  • 任务白屏化日志
  • 关联的绑定机器信息
  • 同步进度、位点细节

4a917e2c-6115-4bd5-a1fa-cd31c8d5d468-image.png

任务内核参数

除任务详情的透明可视化之外,任务内核参数是CloudCanal对于任务精细化控制的重要能力。任务详情中的参数修改支持对任务内核进行更加精细化的控制,以目标端参数配置为例,我们可以控制例如:

  • 异常跳过策略
  • 并行度
  • 约束冲突时的处理策略
  • 对端RPS限流
  • 大小写策略

a1c07ab4-5f60-4986-bbb6-452bb04b519d-image.png

内部组件异常透明化

CloudCanal的管控会搜集所有的异常日志,并且可视化的在控制台展示。核心组件的日志均会分类展示,便于用户快速查看日志和定位问题。CloudCanal会完整毫无遗漏的搜集所有运行时的异常,这也使得一些在日志中隐秘的、偶发的问题直接暴露出来。这些信息都会指导CloudCanal后续的研发,确保产品步步为营、高质量地去迭代升级。 7ac8c7db-ca45-438b-8dad-6c7e279c423f-image.png

运行时信息透明化

CloudCanal的运行时信息透明化主要体现在如下两个维度:

  • 监控
  • 日志

监控

CloudCanal在控制台上即可查看所有组件的监控信息。每个核心组件的监控下按照不同维度会细分多张图表,让用户对核心组件有着完全的掌控。例如增量源端的监控,我们监控会细致到内存队列的阻塞时间、每秒flush事务数等指标。 ac578344-579e-4061-acbc-111c96a0626a-image.png

日志

在CloudCanal平台上提供了核心组件的白屏化日志,并且对日志均按照功能进行了划分。

机器日志

在机器管理处,查看机器日志,我们可以查看机器的完整日志、慢通信日志、异常日志等信息。 aaf203f7-f78f-4bf0-8224-097e84aecb06-image.png

任务日志

在任务详情页,用户则可以查看实时的任务日志,确认任务实时运行状态或者确认问题。 12c847fc-c75b-4e09-9cfa-a807791498fa-image.png

总结

作为面向技术、运维人员的一款数据基础设施产品,在设计之初考虑产品层面的透明化、可视化运维是尤其重要的。这使得产品在后续功能变得越来越复杂和强大时,产品本身依然能够提供高质量的可运维性,同时也确保产品本身能够更好的迭代和发展。

构建实时搜索的选型与思考

· 阅读需 26 分钟
John Li
John Li
Chief Executive Officer

前言

本文具体探讨 MySQL 数据实时同步到 Elasticsearch (以下简称 ES ) 技术方案和思考,同时使用一定篇幅介绍一些前置知识,从理论到实践,让读者更好的理解这块内容和相关问题。包括:

  • 为什么我们要将数据从 MySQL 实时同步到 ES ,本质是什么?
  • 为什么是 ES,而不是其他 OLAP 引擎?
  • MySQL 到 ES 数据实时同步方案中有哪些细节需要注意?
  • MySQL 到 ES 数据实时同步方案可以有哪些选择,优缺点是什么?

相信看完本文,你会对 MySQL 数据实时同步到 ES 有更多的了解。

数据库去规范化

Database normalization is the process of structuring a database, usually a relational database, in accordance with a series of so-called normal forms in order to reduce data redundancy and improve data integrity. It was first proposed by Edgar F. Codd as part of his relational model.

数据库规范化是指关系型数据库中通过一系列数据库范式来减少数据冗余、增强数据一致性的策略。例如我们平时使用的关系型数据库的关系模型可以认为是 Database Normalization 的一种实现方式,这些关系型数据库基本都至少遵循了数据库第三范式,可以称之为 Normalized Database。关于数据库范式的内容,本文不再展开。

Denormalization is a strategy used on a previously-normalized database to increase performance. In computing, denormalization is the process of trying to improve the read performance of a database, at the expense of losing some write performance, by adding redundant copies of data or by grouping data.[1][2] It is often motivated by performance or scalability in relational database software needing to carry out very large numbers of read operations. Denormalization differs from the unnormalized form in that denormalization benefits can only be fully realized on a data model that is otherwise normalized.

Database Normalization 在带来我们看得见的好处同时(利于事务操作性能、存储成本降低),伴随数据规模扩大、并发度提高、复杂度上升,弊端也慢慢展现,这时候 Database Denormalization 能够一定程度满足这些挑战,总体思路是通过一系列降低写入性能的操作例如更多的数据冗余、数据分组等来提升数据库读取的性能。

去规范化的时机

数据去规范化动机多样,当出现因数据复杂操作影响系统稳定性、业务响应/并发要求不满足等都是触发因素。

业务稳定性问题:面向 C 端的互联网应用特征是并发量较高,SQL 偏向点查点写,相对简单,但是沉淀下来的数据(比如订单、支付等) 需要做运营往往涉及传统企业级应用对于数据库的操作特征,大范围数据栅查、表关联、排序等实时操作,以及满足报表/BI等更加复杂的数据库需求。通过去规范化和负载分离是较合理的选择。

复杂查询性能问题:企业级应用例如ERP、CRM、BOSS或者其他一些企业运营系统,经常涉及表关联、聚合、多维删选、排序等操作,并常常带来性能问题。通过去规范化的一些方式,如下文提到的数据冗余和预计算方式,显著改善性能。

去规范化的几种实现方式

假设有如下三张表,学生、班级和教师。需求是:已知学生的学号,需要查询当前学生的班主任是名字。

08628470-bda8-4887-8db0-b6bac0ff78d3-image.png

使用规范化数据查询,是一个 3 表联查操作,而在数据库中,大体分三步:

  • 通过学生学号获取学生信息,得到班级编号
  • 通过班级编号获取班级信息,得到班主任工号
  • 通过班主任工号得到教师信息,得到班主任的名字

如果在数据量较大,有一定并发要求,并且涉及更多表关联时候,这种计算就不能满足需求,这个时候去规范化的优化方式就登场了。

列级处理——主查询表冗余字段

通过在主表冗余计算好的数据,可避免频繁重复计算数据。如下场景适合在主数据表内冗余数据:

  • 应用系统需要经常获取计算好的数据
  • 用于计算 calculated data 的原始数据不经常变化

在学生表冗余班主任的名字信息,表的设计变为如下:

b2781619-2e40-4b3c-bcb6-6bbedab68574-image.png

这时候查询就只有一步了: 根据序号获取学生信息,同时也得到了其班主任名字的信息

优点:方法较为简单易懂,容易实现。 缺点:侵入业务逻辑,拖慢业务代码性能的同时,长期迭代所产生的变化可能会有稳定性风险。

表级处理——宽表预构建/Cube预构建

表级处理主要操作就是构建宽表,或者构建数据立方体(Data Cube)。构建好的宽表包含了用户查询时需要的所有维度、度量信息。以上面学生查找班主任的问题为例,构建的宽表结构如下。

4577b645-9258-4684-88d5-5f3fa2a94b04-image.png

表级处理常见实现方式包括 应用多写、数据库自身实现的物化视图、数据迁移同步。

应用多写

在主数据相同数据库内创建宽表,应用写入数据的时候同时也向宽表写入数据(事务保证一致性),复杂查询即可从该表进行。

优点:实现简单、低成本 缺点:对主数据库造成更大的读写压力,外加业务改造成本。

RDBMS 物化视图

Oracle、SqlServer 等数据库物化视图方案,通过数据冗余与预计算减少 join、聚合,从而提升查询性能。例如,在 Oracle 上完成学生查找班主任这个查询,可以构建一张“学生管理表”的物化视图,查询请求直接请求物化视图即可得到查询结果,避免 join ,显著改善该 SQL 执行效率。

优点:数据库引擎自身支持,使用成本较低 缺点:RDBMS 实现的方式有自己的局限性,比如生成物化视图的数据需要做一些业务紧相关变换就无法满足,或者某些数据库并没有完整实现该能力(物化视图在 2000 年左右是数据库学术圈研究的重点)。

数据迁移同步

借助数据同步工具,准实时将主数据表数据组织变换(包括按照业务逻辑变换)形成普通表或大宽表,写入第三方存储引擎(如 OLAP 存储引擎或者搜索系统)。复杂查询直接在预构建好的表上或者 cube 上执行,从而达到良好的性能。数据迁移工具的选择较多,总体上按照其侧重点,可以分为如下几类:

  • 大数据类:为大数据产品流入数据提供服务,因为大数据产品本身特点,侧重批量定时的迁移,实时同步一般需要用特别的方法,往往和业务特征紧耦合。常见的数据迁移同步工具有 sqoopdatax
  • 流计算类:为自身流计算框架生态服务,侧重计算,迁移同步更多是类似数据连接器的角色,代表的产品如 Flink
  • 消息类:为自身消息产品生态服务,如丰富的 kafka connectordebezium
  • 数据库类:数据库厂家一般都会提供原厂工具,典型如 Oracle 的 GoldenGate
  • 云厂商类:云厂商提供的数据迁移同步工具,主要侧重自身云上数据库生态产品之间的互融互通和将线下自建数据库的数据上云,例如阿里云 DTS, 腾讯云 DTS , AWS 的 DMS
  • 专业数据迁移同步工具: 包括部分开源产品或第三方独立公司提供的数据迁移同步工具,例如 canalstreamsetsmaxwellcloudcanalstriimfivetran ,以及老牌数据集成厂商 InformaticaQlik 等所提供的产品

优点: 主库更稳定:异步化解耦业务系统事务查询和复杂查询,避免复杂查询对主数据库产生影响 易运维、链路稳定:数据迁移同步链路有标准化产品支撑,和主业务系统、主库读写解耦。整体架构上职责清晰,易于维护和问题追踪 缺点: 需要对纷繁多样的数据迁移同步工具、承载复杂查询数据库产品选型,对技术同学能力有一定要求

MySQL 到 ES 数据实时同步技术架构

我们已经讨论了数据去规范化的几种实现方式。MySQL 到 ES 数据同步本质上是数据去规范化多种实现方式中的一种,即通过“数据迁移同步”构建高效数据应用,解决规范化数据复杂查询的效率问题。本节我们分享下“MySQL 到 ES 数据迁移同步”项目时可选的比较常见的两种技术架构,通过比较他们的优缺点和应用场景给读者后续架构选型时提供一些思路。

为什么是 MySQL

MySQL 在关系型数据库历史上并没有特别优势的位置,Oracle/DB2/PostgreSQL(Ingres) 三老比 MySQL 开发早了 20 来年, 但是乘着 2000 年的互联网东风, LAMP 架构得到迅速的使用,特别在中国,大部分新兴企业的 IT 系统主数据沉淀于 MySQL 中。

  • 高并发能力:MySQL 内核特征特别适合高并发简单 SQL 操作 ,链接轻量化(线程模式),优化器、执行器、事务引擎相对简单粗暴,存储引擎做得比较细致
  • 稳定性好:主数据库最大的要求就是稳定、不丢数据,MySQL 内核特征反倒让其特点鲜明,从而达到很好的稳定性,主备系统也很早就 ready ,应对崩溃情况下的快速切换,innodb 存储引擎也保障了 MySQL 下盘稳定
  • 操作便捷:良好、便捷的用户体验(相比 PostgreSQL) , 让应用开发者非常容易上手 ,学习成本较低
  • 开源生态:MySQL 是一款开源产品,让上下游厂商围绕其构建工具相对简单,HA proxy、分库分表中间件让其实用性大大加强,同时开源的特质让其有大量的用户

为什么是 ES

ES 几个显著的特点,能够有效补足 MySQL 在企业级数据操作场景的缺陷,而这也是我们将其选择作为下游数据源重要原因

  • 文本搜索能力:ES 是基于倒排索引实现的搜索系统,配合多样的分词器,在文本模糊匹配搜索上表现得比较好,业务场景广泛
  • 多维栅选性能好:亿级规模数据使用宽表预构建(消除 join),配合全字段索引,使 ES 在多维删选能力上具备压倒性优势,而这个能力是诸如 CRM, BOSS, MIS 等企业运营系统核心诉求,加上文本搜索能力,独此一家
  • 开源和商业并行:ES 开源生态非常活跃,具备大量的用户群体,同时其背后也有独立的商业公司支撑,而这让用户根据自身特点有了更加多样、渐进的选择

为什么是数据迁移同步方式

相对于数据去规范化的其他几种方案,数据迁移同步方式存在以下几个优点,也是其成为目前业界主流方式的原因

  • 稳定性好:迁移同步对主数据库的操作主要是进行数据和日志的顺序读取,同时并发小,对主数据库稳定性影响较小(较多的下游订阅可能在网络层面存在影响,一般用消息解决)。另外日志(Binlog/WAL/Redo等)可重放特质,让下游丢数据的可能性大大减小(处理好幂等的情况下)
  • 业务解耦:一般而言主数据库更多承载事务型操作,而下游数据系统承载运营等层面的业务, 典型如电商的买家侧和卖家侧业务
  • 业务侵入小:数据迁移同步对业务无侵入,双端对接标准数据库(源),可以便利地找到开源、商业、云等各个方向的成熟解决方案或产品
  • 业务适配性好:某些数据迁移同步产品能够嵌入业务逻辑,让下游获取到更加贴近业务的数据,从而让数据服务更加有效和便捷

数据迁移同步模型选择

订阅消费

5e69e98e-0245-45d9-b8ca-b136c2e799bc-image.png

优点

  • 堆积能力:由于引入了消息队列,所以整个链路是具备变更数据的堆积能力的。假设变更数据消费的比较慢,MySQL 本地较老的 binlog 文件由于磁盘空间的不足而被删除时,消息队列中的数据仍然存在,数据同步仍然可以正常进行
  • 数据分发能力:引入消息队列后可以支持多方订阅。如果下游多个应用都依赖源端的变更数据,可以订阅同一份 topic 即可
  • 数据加工能力:由于变更数据是由下游消费者订阅,因此订阅后可以灵活的做一些数据加工。例如从外部调用微服务接口或者反查一些数据来做数据加工都是比较方便的

缺点

  • 运维成本相对较高:整体链路较长,端到端的数据同步链路包含了较多的组件和应用,运维要保证整体链路的稳定性需要关注更多的组件和应用
  • 稳定性风险较高:由于端到端链路较长,整个链路中的一环出问题会导致整个端到端数据同步的稳定性。而且由于链路较长,排查和定位问题的时候也会困难很多

端到端直连

c1b98064-7e4e-4487-97a6-0f71051e5cab-image.png

优点

  • 低延迟:端到端的直接同步,链路较短,延迟低
  • 稳定性好:链路组件少,出问题概率较低,定位排查均比较容易。适合对数据精确性高的严苛场景。
  • 功能拓展性强:对端写入消息系统,模拟订阅模式,可扩展性强
  • 运维部署简单:链路组件少,部署运维更简单

缺点

数据迁移同步模型选择总结

从笔者以往的经验来看,如果没有众多的下游数据订阅,建议采用直连模式。数据同步链路往往置于在线业务中,随着业务规模以及重要性逐渐加大,链路 稳定性 更为重要些。

不过 端到端模式 只要支持对端数据源为消息中间件,可立刻实现订阅模式,数据加工能力在某些数据迁移同步产品上可通过上传业务代码运行的方式解决。

另外,数据架构在满足业务需求的同时,简洁和清晰能够让系统更加易于维护和排查,当遇到链路每天同步几千万条上亿条数据、偶发丢几条需要排查,或同步链路卡住不同步等情况,端到端方式往往体现出相当大的优势。

MySQL 到 ES 数据实时同步核心挑战

关系型数据库中不同表之间的数据常存在关联,同步到 ES 之后,这种关联关系该如何去组织,同时又能够很好的匹配到 ES 的最佳实践 ? 本小节会展开讨论这个问题,并对常见的数据同步工具选型提供一些参考对比。

MySQL 关联表在 ES 上的设计

关系型数据库库中的表 join 关系在 ES 可以用几种数据类型来表达,包括 objected , nested , join 三种。

objected

object 类型可以存储嵌套结构.

优点

表示主 field 和 object 内部 field 之间的一对多关系,支持 doc 的 join 查询。由于所有查询时依赖的关联数据也都在一个文档内,避免了 ES 内部的 join,查询效率较高。

缺点

一对多关系只能保留一层,多于一层的会被打平,会丢失嵌套 field 内部的关联关系。下面的例子中,第一幅图看到写入 ES 的是一条订单数据,其中 producets 这个 field 是 object 类型,其中包含了多个产品的记录。

当采用 objected 字段存储 products 信息时,原本存储的信息如下:

"order_id" : 123,

"products" : [

{
"price" : 10,
"sku" : "SKU_10",
},
{
"price" : 20,
"sku" : "SKU_20",
}
]

在ES中存储的样子为:

{

"order_id": [ 123 ],
"products.price": [ 10, 20],
"products.sku": [ SKU_10, SKU_20 ],
}

可以看到在ES的存储中,producets 中每个字段的值都已经被打平处理。如果我们查询订单 ID 为 123,价格 price 为 10,SKU 为 “SKU_20” 的文档,我们同样可以搜索到结果,但这样显然就丢失了其内部之间的关系了。

nested

nested 类型可以存储嵌套结构,表示一对多关系,是 object 类型的拓展

优点

  • 不会出现 object 的缺点,整个嵌套关系是完整维护的,子文档内部的关联关系保存是完整的
  • 关联数据通过实现上自然关联到主文档上,搜索时性能较好(相对于 join 类型)

缺点

  • 一个 nested field 只能属于一个主文档
  • 在 nested 类型中,子文档和主文档之间是强绑定,主文档更新的时候会强制更新子文档。在写多读少的场景,性能开销较大
  • child 文档的查询必须通过父文档再找到子文档
  • 子文档频繁修改的话会影响别的子文档和父文档,因为本质上在 lucence 实现上是父文档下的冗余存储
join

join 类型可以配置父子文档,通过父子文档来实现一对多的能力,一个索引只能建一个。相比 nested 类型,该类型更加灵活。父子文档之间通过 parentId 来关联,实际实现上他们就是独立的文档。因此带来的好处主要是

优点

  • 子文档更新不影响父文档和其他子文档
  • 一个子文档可以单独搜索
  • 一个文档在作为子文档时可以自己选择属于哪个父文档。通过relation可以指定不同的join列

缺点

  • 需要建个全局序数,用于服务于父子文档的关联关系,这个会影响搜索性能
join 和 nested 类型比较

join 适合写多读少场景,更加适合关注索引性能的场景。这意味着更新的生效会更快,但是搜索时的开销也相对大些, nested 适合读多写少的场景,更加关注搜索的性能

MySQL 到 ES 实时数据同步实现去规范化

在了解 ES 的一些关键类型之后,我们就可以描述通过数据同步去规范化的几种实现方式。

主表冗余数据

业务侧将一些查询时需要的关系数据提前冗余在源表的一个字段中。例如序列化成json存储在源表的一个冗余字段内,利用数据同步工具写入对端 ES 的 join/nested 类型字段。例如我们有订单表和商品表如下图所示。假设我们的搜索需求是,给定一个订单ID,同时将这个订单的订单明细以及所有包含的多件商品的明细全部搜索出来。

670def7c-7a2e-4139-89d3-0bece5b44eb4-image.png

如果采用这种列级处理模式,我们在订单表新增一个冗余列,然后将商品表的所有明细信息,按照kv组织成json写入冗余列即可,如下图所示。对端 ES 的 mapping 结构按照如下方式定义。数据同步工具直接将该保函关联表数据的订单表直接同步到对端 ES ,即可在 ES 上搜索符合我们需求的数据。

9ad1e826-27c3-4432-b7a8-9e857158ea10-image.png

{
"mappings": {
"_doc": {
"properties": {
"order_id": {
"type": "long"
},
"order_price": {
"type": "long"
},
"product_count": {
"type": "long"
},
"discount": {
"type": "long"
},
"product_info": {
"type": "nested"
},
}
}
}
}

优点

  • 处理模式能应对各种一对多的关联关系,对数据同步工具的功能要求低,配置简单,只需要支持单表同步到 ES 即可。

缺点

  • 索引、搜索性能非最佳:提供给 ES 的不是预构建好的宽表数据。例如例子中,订单关联的商品信息,全部存储在主表的一个object/nested/join 字段内,这种实现方式会有索引、搜索性能方面的额外开销,不是性能最佳的实现方式
  • 业务系统侵入:业务系统写主数据的时候需要额外写入信息
  • 主数据库表冗余过多数据:关系型数据库的表冗余了过多其他表的信息,可能存在存储和性能开销

总结

  • 不太推荐该方式
多表订阅合并预构建宽表数据

数据同步工具同时订阅搜索时依赖的所有表,先到的数据先进到 ES,没有数据过来的字段为空。以上面提到的订单和商品表的例子来说,即同时同步订单表和商品表到对端索引。对端索引的 mapping 定义如下所示,包含订单和商品表的所有字段,定义的索引是一张宽表。流计算中多流汇聚配合时间窗口 join 多表的方式与该种方式有异曲同工之处。

优点

  • 数据同步工具配置同步任务较为简单,无业务入侵,不耦合业务系统逻辑
  • 对数据同步工具要求低,除了同步以外,不需要其他额外的功能特性
  • 基于预构建宽表的方式在 ES 上也有较好的索引和查询性能[7]。
  • 同步链路不会因为宽表某些列缺失数据阻塞整个数据链路的同步(是否有该优点取决于数据同步工具本身设计,如果引入时间窗口,则同步链路会因为等待列数据影响同步时效性)。

缺点

  • 基于事实表主动触发式的方式来进行宽表的构建。源端订阅的表,如果更新很少或者从来不更新产生 binlog,则对端的文档中的列值可能一直不完整,导致时效性会比较差。搜索的时候有一些列的数据会缺少

总结

  • 适合构成宽表的事实表数据写入有事务保证一起落盘的场景,这样可以避免对端ES搜索到不完整的数据。
  • 适合构建宽表不需要业务加工处理的场景,构建宽表只是单纯的将多张表的列拼接在一起,形成宽表。
{
"mappings": {
"_doc": {
"properties": {
"order_id": {
"type": "long"
},
"order_price": {
"type": "long"
},
"product_count": {
"type": "long"
},
"discount": {
"type": "long"
},
"product_id": {
"type": "long"
},
"product_unit_price": {
"type": "long"
},
"product_name": {
"type": "text"
},
}
}
}
}
同步过程回查预构建

数据同步工具订阅的表称为主表。数据同步过程中,反查数据库查询的表称为从表。利用数据同步工具自身的能力,在订阅主表期间,自动通过回查的方式,填补宽表中的列,形成完整的宽表行数据。对端 ES 的mapping 定义例子与“多表订阅合并预构建宽表数据”中的保持相同。

优点

  • 基于反查的方式构建宽表灵活性好,可以在生成宽表前基于主表的数据对从表数据做一些轻度的数据加工
  • 一条主表的数据,通过反查生成宽表行,可以配合数据加工生成多条宽表行数据
  • 基于反查的方式可以比较轻松的实现跨实例的 join ,从而生成宽表行(相对好实现,具体要看数据同步工具本身是否支持)
  • 基于宽表预构建的方式在 ES 上有较好的索引、查询性能[7]。

缺点

  • 反查时数据可能没有准备好,导致数据缺失(这里具体的影响取决于数据同步工具本身设计,可以引入时间窗口配合超时等待,也可以没有数据时直接同步到对端)
  • 需要数据同步工具在数据反查、数据加工方面进行支持

总结

  • 对于构建宽表涉及数据加工的场景,该方式比较适合。
  • 由于该方式的回查机制、预构建前数据加工的能力支持,能力上是“多表订阅合并预构建宽表数据”这种方式的超集。如果有比较好的数据同步工具支持,这种方式是比较推荐的。

数据迁移同步工具选型

数据迁移同步工具的选择比较多样,下表仅从 MySQL 同步 ES 这个场景下,对一些笔者深度使用研究过的数据同步工具进行对比(不一定精确,如有错误请联系笔者更正),用户可以根据自己的实际需要选取适合自己的产品。

特性\产品Canal云DTSCloudCanal
系统部署❌ 手动部署,并基于配置文件去配置,初次上手有门槛
❌ 不支持端到端直接同步,需要先从mq中订阅数据后才可投递到es,链路长,部署复杂度提升。
✅ 用户私有化部署
✅ saas化产品,开箱即用
❌ 不支持私网内数据同步,强依赖阿里云
❌ 私有化部署
✅ saas化产品,开箱即用
✅ 可直接从源端数据库订阅投递到es
✅ 私有化部署
同步模型订阅消费模型直连模式直连模式
版本支持✅ 支持自建的es6和es7或者阿里云es✅ 只支持阿里云es及其提供的版本
❌ 不支持开源自建es
✅ 支持自建es6和es7以及阿里云的es6和es7
产品化❌ 有Admin管控控制台,但是比较简陋,产品化程度较低,监控报警审计功能不完整、无可视化创建任务等能力✅ 有一定产品化能力,例如可视化创建、性能监控等✅ 完整的产品化能力包括数据源管理、机器管理、监控、报警、审计、性能指标、白屏化日志、参数配置等
结构迁移❌ 不支持✅ 仅支持同步到全新索引✅ 支持全局的索引分片数、分区副本数设置
❌ 不支持表级的索引分片数、分区副本数设置
❌ 不支持列映射、列自动创建
✅ 可同步到已存在的索引,支持索引自动创建、列映射、列自动创建
✅ 支持表级别的索引分片数、分区副本数设置
全量迁移❌ 不支持✅ 支持✅ 支持
增量同步✅ 支持✅ 支持✅ 支持
过滤条件✅ 支持,基于配置文件配置
❌ 产品化配置
✅ 产品化能力支持✅ 产品化能力支持
时区❌ 不支持时区转换,采用同步机器时区
❌ 对端索引时间类型format和源端同步数据的format不一致会有精度丢失问题
✅ 支持全局时区转换配置
❌ 只支持同步到新建的索引表,精度不可更改,对已存在索引的同步支持不佳
✅ 支持全局时区转换配置
✅ 全量、增量支持自动识别对端已经存在的索引的format和精度进行写入
特殊类型支持❌ 不支持源端json类型
✅ 支持对端object/nested/join类型,但是需手动配置
❌ 不支持选择nested类型
✅ 新建表支持映射object,但是无法映射nested类型
✅支持源端json类型
✅支持json类型自由映射对端object/nested类型
join支持✅ 支持。基于父子文档的join方案
❌ join方案会影响搜索性能。基于父子文档的join方案,缺点是会影响对应索引搜索的效率,因为会构建全局序数
❌ 无join支持✅ 支持基于反查预先构建宽表的能力,有最好的写入和搜索性能[7]
成本和服务支持开源产品无额外成本,但是也没有商业化的服务支持small规格的mysql->es链路价格为1.78元/每小时,成本较高(2020年12月2日价格),没有专属的服务支持群,问题需要统一走阿里云工单CloudCanal社区版功能完整,免费使用。有活跃的社区支持。同时提供企业版商业化产品,有SLA保障和专业的专家服务支持

写在最后

MySQL 到 ES 数据同步构建数据检索服务给中小企业带来了稳定且实用的在线数据方案,在满足业务诉求(高并发业务与企业级应用常态化)的同时 ,易上手且具备不错的可维护性,在适当的场景下,值得尝试和实践。

最后感谢各位的阅读,内容相对浅显且直接,希望对你有所帮助和启发。在此也简单介绍下笔者自己,本人在阿里巴巴中间件和云智能团队从事过几年时间数据相关工作,在该领域具备一定的经验,对这个方向感兴趣的朋友可以一起探讨相关技术问题。

参考资料

[1] 维基百科:Database normalization [2] 维基百科:Denormalization [3] When and How You Should Denormalize a Relational Database [4] 爱奇艺|海量数据实时分析服务技术架构演进 [5] 从 ES 到 Kylin,斗鱼客户端性能分析平台进化之旅 [6] 常见开源OLAP技术架构对比 [7] Elasticsearch:Tune for search speed [8] Elasticsearch:Field data types [9] Designing Data-Intensive Applications [10] Materialized Views [11] A Relational Model of Data for Large Shared Data Banks

CloudCanal x TiDB 数据迁移同步

· 阅读需 6 分钟
John Li
John Li
Chief Executive Officer

简介

TiDB 是一款由 PingCAP 开源的 分布式关系型 数据库,主打 HTAP 能力,具备 优秀的伸缩性。其开源社区强大,产品颇具流行度。

数据同步场景中,TiDB 官方提供如 TiCDC、TiDB Binlog 等工具,但为了满足用户将 TiDB 数据迁移同步到更加广泛数据库的需求,CloudCanal 近期推出了 TiDB 为源端的数据迁移同步 功能,本文将简要介绍该能力的落地。

功能介绍

目标数据库和能力

目标端数据源结构迁移数据初始化增量同步数据校验数据订正
MySQL支持支持支持支持支持
TiDB支持支持支持支持支持

目标数据源不断增加中

TiDB 源端特色能力

不依赖 TiCDC

TiDB 为源端的增量数据同步实现有两种方式

  • 作为 TiCDC 下游接收变更记录,实现数据同步
  • 与 TiKV/PD 直接通信,接收实时变更数据,实现数据同步

CloudCanal 考虑到部署的 轻量性可控性,选择了第二种方案,跳过 TiCDC、TiDB Server 组件,直接与 PD 建立 gRPC 通信,实时接收源端数据变更记录,通过算法解析字节流内容,自动同步到对端数据库中。

支持断点续传

长周期数据同步,任务可能会因为参数调整问题数据修复性能优化等操作暂停或重启任务,断点续传能力不可或缺。

CloudCanal 为 TiDB 源端定时或定量保存对端消费后的位点,以实现断点续传能力。

全量迁移中,对亿级别数据量的大表中断重启,断点续传能力可尽可能少的影响迁移进度,增量同步中,断点续传能力确保任务重启后可继续,并不丢失数据。

变更事件保序

订阅 TiDB 增量变更事件,可能因为各种原因,个别变更数据到达时间不一致(乱序),导致数据丢失或变更错误。

CloudCanal 为此采用自研算法处理事件,并根据事务 最终提交时间 来保证事务的有序消费。

支持 DDL、DML 增量数据同步

CloudCanal 支持以 TiDB 为源端,TiDB、MySQL 为对端 (支持的对端数据源还在不断增加) 的 DDL 和 DML 同步。

  • DDL 数据同步能力:

    • ALTER TABLE ... ADD/DROP/MODIFY COLUMN ...
    • ALTER TABLE ... ADD/ALTER/DROP INDEX ...
    • RENAME TABLE ... TO ...
  • DML 数据同步能力

    • INSERT/UPDATE/DELETE

除了 DDL、DML 同步功能实现,CloudCanal 根据 SCHEMA SNAPSHOT 和 DDL 构建了表 多版本表快照能力,确保变更数据和结构保持一致,数据消费更加精准。

结构迁移类型自动处理与优化

不同数据库对于数据类型支持存在差异,CloudCanal 结构迁移时会进行类型自动转换与优化。

TiDB 为源端的结构迁移也存在类似转换与优化,如以 MySQL 为对端的 Float 类型若不指定精度,则可能造成数据精度丢失, CloudCanal 将 Float 类型自动转换为 Float(0),保证了精度的准确性

配套数据校验与订正能力

在数据同步过程中,由于数据的外部关联性结构约束差异数据库运维操作软件bug等情况,两端数据可能会不一致,此时数据校验和订正功能非常必要。

CloudCanal 为 TiDB 为源端的数据同步能力额外提供了数字、字符类型主键表的数据校验数据订正功能,快速确定不一致数据范围,并针对差异数据进行修复。

产品化能力支撑

可视化创建

CloudCanal 创建 TiDB 数据迁移同步任务是完全可视化的,通过获取数据库元数据,让用户在 web 页面上决定哪些库、表、列进行迁移同步,或者设定过滤条件自定义数据处理逻辑等。

自动化流程

TiDB 数据迁移同步任务创建后,CloudCanal 将自动流转各个阶段的任务,用户无需干涉,直达数据实时同步状态。

监控图表支撑

CloudCanal 为 TiDB 数据迁移同步任务提供了多个实用监控指标,包括增量缓存RPS增量缓存延迟(ms)内存队列数据个数等,当调优任务性能或排查任务异常原因时,监控指标提供了很好的判断依据。

告警支持

CloudCanal 为 TiDB 数据迁移任务提供了包括钉钉/企业微信/飞书/自定义等 webhook 类型告警,对于企业级客户,可额外选择邮件,以及短信告警,实时保障同步任务的高可用。

简单示例

本示例以将数据从 TiDB 数据库同步到 MySQL 数据库为操作案例,以便更好地说明 CloudCanal 在不同数据库之间进行数据同步的能力。

准备动作

  • 下载安装 CloudCanal 私有部署版本,使用参见快速上手文档
  • 准备好 TiDB 数据库(本例使用 5.4.3 版本)和 MySQL 数据库(本例使用 8.0 版本)
  • 登录 CloudCanal 平台 ,添加 TiDB 和 MySQL
  • TiDB 增量同步依赖 PD 通信,如需进行增量同步,请在额外参数处填写 PD 地址

任务创建

  • 任务管理 -> 新建任务

  • 测试链接并选择 源 和 目标 数据库

  • 点击下一步

  • 选择 数据同步,并勾选 全量数据初始化,其他选项默认

  • 选择需要迁移同步的表和列 (本例以常见的 数字、字符、时间类型主键、多主键表为例)

  • 确认创建任务

  • 任务自动执行结构迁移、全量同步和增量同步,执行一些增量数据同步后进行数据校验,结果显示数据校验通过

总结

本文主要介绍了 CloudCanal 支持 TiDB 为源端数据迁移同步功能,通过这个能力,用户可以便利地将 TiDB 中数据实时同步到其他数据库,实现数据更广泛、更实时的应用。