可视化数据同步迁移工具 CloudCanal

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 可视化数据同步迁移工具 CloudCanal

image.pngCloudCanal 核心团队成员来自阿里巴巴中间件和数据库团队, 长期从事分布式数据库、数据库中间件、应用中间件工作。CloudCanal 在 MySQL binlog 解析使用了 Canal 部分代码,其他均为自主研发,并且对 Canal 部分代码进行了大量重构,修复诸多问题并优化性能。Canal 在 CloudCanal 中的位置,可以用以下图片简单表示,可见 Canal 代码在 CloudCanal 产品中只占很小一部分。image.png

CloudCanal 高可用部署

准备工作

安装 Docker

不同操作系统可以参考 Docker 官网文档 进行安装。

安装 Docker Compose

这里提供一个国内的镜像站的安装命令,也可以参考 Docker-Compose 安装文档。

curl -L https://get.daocloud.io/docker/compose/releases/download/1.28.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

安装 7z

收到的安装包为 cloudcanal.7z,其中包含了镜像和管理脚本。需要通过安装和使用 7z 命令进行解压。

### 安装7z命令(centos系)
sudo yum install p7zip p7zip-plugins
### 安装7z命令(ubuntu系)
sudo apt-get install p7zip-full p7zip-rar
### 安装7z命令(macOS)
brew install 7z
### 进到安装包所在路径,执行以下命令进行解压缩
7z x cloudcanal.7z

如果无法通过 yum 或者 apt 等源直接安装,可以通过编译的方式安装。

wget http://nchc.dl.sourceforge.net/sourceforge/p7zip/p7zip_4.65_src_all.tar.bz2
tar -xjvf p7zip_4.65_src_all.tar.bz2
cd p7zip_4.65
make
make install

然后使用 7za 命令解压。

7za x cloudcanal.7z

解压后目录如下,主要分为三大块:

  • 镜像:包含四个 tar 压缩文件。
  • 脚本:启动、更新和停止,以及 scripts 运维脚本目录。
  • 日志与配置文件:日志为 docker-compose 启动日志,配置文件为 docker-compose 配置文件。
[root@master1 chengzw]# ls -l cloudcanal
总用量 2939372
-rw------- 1 root awx  912166912 8月  31 19:34 console.tar
-rw-r--r-- 1 root awx   12211728 8月  31 15:27 docker-compose
-rw-r--r-- 1 root awx        320 8月  31 19:29 docker-compose-sidecar.yml
-rw-r--r-- 1 root awx       1418 8月  31 19:29 docker-compose.yml
-rw------- 1 root awx  453986816 8月  31 19:32 mysql.tar
-rw------- 1 root awx  190344192 8月  31 19:37 prometheus.tar
drwxr-xr-x 2 root awx        180 8月  31 19:29 scripts
-rwxr-xr-x 1 root awx         63 8月  31 19:29 shutdown.sh
-rw------- 1 root awx 1441171968 8月  31 19:37 sidecar.tar
-rwxr-xr-x 1 root awx       1211 8月  31 19:29 startNewSidecar.sh
-rwxr-xr-x 1 root awx       2682 8月  31 19:29 startup.sh
-rwxr-xr-x 1 root awx       2031 8月  31 19:29 upgrade.sh
-rw-r--r-- 1 root awx        376 8月  31 19:29 使用必读.txt

启动 CloudCanal

在解压的路径下可以执行以下命令启动 CloudCanal。

sh startup.sh

当终端出现 cloudcanal start 时,表示启动成功。可以访问 http://${部署机器ip}:8111 来登录 CloudCanal。image.png

默认自带的测试数据库

默认帮添加好了测试的 MySQL 数据源,其中 cloudcanal_test_a (源端)和cloudcanal_test_b (目标端)这两个库中已经帮准备好了用于测试的表和数据,可以方便您体验整个流程。

  • 默认已经添加了一台运行机器,用于执行具体的数据同步任务,所以直接添加数据源即可开始创建同步任务。
  • 遇到需要发送短信的场景,先点击获取验证码,然后输入短信验证码 777777 即可。

在宿主机上可以直接以下命令访问 MySQL 容器。

docker exec -it cloudcanal-mysql  mysql -uclougence -h127.1 -p123456

image.pngimage.pngimage.pngimage.png

在另一台机器上启动新的 Sidecar 容器

首先将 CloudCanal 的安装包在待部署的新机器上解压。在安装包目录下,执行如下命令添加一台新的 Sidecar 容器。注意在一台机器上不允许启动两个 Sidecar 容器,请在新的机器上启动 Sidecar 容器。

sh startNewSidecar.sh

复制机器唯一标识到容器内指定配置文件内。先进入 Sidecar 容器。

docker exec -it cloudcanal-sidecar /bin/bash

在 Sidecar 容器内修改配置文件:vi /home/clougence/cloudcanal/global_conf/conf.properties。

cloudcanal.auth.ak=ak0a2c62tdo1ap2416655mpyx0v36l359p1v5rn782caw8t0qkk1s94b80lfs90
cloudcanal.auth.sk=sk6206iy4pb0eydz9hg97jo3tu5d80j97e91bbql65167u8wb75x4ej6e4v4aa4
cloudcanal.sidecar.wsn=wsnd0ndmrhsm9yu9lj06897h4cvh42br0s5c1e4iut0e93g78as46t7oe5k04fi3
# 替换 cloudcanal.console.domain 的值为 console 容器所在宿主机的内网ip
cloudcanal.console.domain=11.8.36.104

修改完成后,修改目录权限:

chown -R  clougence:clougence /home/clougence/cloudcanal

然后切换到 clougence 用户启动 Sidecar 进程。

sh /home/clougence/cloudcanal/sidecar/bin/startSidecar.sh
## 查看日志,确认是否有异常。如果都为INFO或者WARN日志就是正常的
tail -f /home/clougence/logs/cloudcanal/sidecar/sidecar.log

在控制台界面可以看到机器成功注册。image.png

CloudCanal 升级

解压新版本的 cloudcanal.7z 压缩包,覆盖原目录下相同的文件,然后依次执行以下脚本即可。

sh upgrade.sh
sh startup.sh

因为数据目录 sidecar_data 和 console_dat 不会被覆盖,因此数据不会丢失。

添加数据源

进入数据源管理界面,点击添加数据源,可以选择阿里云上的数据源或者自建数据库。image.png

准备数据

使用 Percona 公司提供工具来随机生成数据,github 地址:https://github.com/Percona-Lab/mysql_random_data_load/releases

执行以下命令下载并解压工具。

wget https://github.com/Percona-Lab/mysql_random_data_load/releases/download/v0.1.12/mysql_random_data_load_0.1.12_Linux_x86_64.tar.gz
tar -xzvf mysql_random_data_load_0.1.12_Linux_x86_64.tar.gz

在源库创建一张表:

CREATE TABLE `acpcanaldb`.`t7` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `tcol01` tinyint(4) DEFAULT NULL,
  `tcol02` smallint(6) DEFAULT NULL,
  `tcol03` mediumint(9) DEFAULT NULL,
  `tcol04` int(11) DEFAULT NULL,
  `tcol05` bigint(20) DEFAULT NULL,
  `tcol06` float DEFAULT NULL,
  `tcol07` double DEFAULT NULL,
  `tcol08` decimal(10,2) DEFAULT NULL,
  `tcol09` date DEFAULT NULL,
  `tcol10` datetime DEFAULT NULL,
  `tcol11` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `tcol12` time DEFAULT NULL,
  `tcol13` year(4) DEFAULT NULL,
  `tcol14` varchar(100) DEFAULT NULL,
  `tcol15` char(2) DEFAULT NULL,
  `tcol16` blob,
  `tcol17` text,
  `tcol18` mediumtext,
  `tcol19` mediumblob,
  `tcol20` longblob,
  `tcol21` longtext,
  `tcol22` mediumtext,
  `tcol23` varchar(3) DEFAULT NULL,
  `tcol24` varbinary(10) DEFAULT NULL,
  `tcol25` enum('a','b','c') DEFAULT NULL,
  `tcol26` set('red','green','blue') DEFAULT NULL,
  `tcol27` float(5,3) DEFAULT NULL,
  `tcol28` double(4,2) DEFAULT NULL,
  `tcol29` varchar(5000) DEFAULT NULL,
  `tcol30` varchar(5000) DEFAULT NULL,
  `tcol31` varchar(5000) DEFAULT NULL,
  `tcol32` blob,
  `tcol33` blob,
  `tcol34` blob,
  `tcol35` blob,
  `tcol36` blob,
  `tcol37` blob,
  `tcol38` blob,
  `tcol39` blob,
  `tcol40` blob,
  `tcol41` blob,
  `tcol42` blob,
  `tcol43` blob,
  `tcol44` blob,
  `tcol45` blob,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

使用工具持续往源库插入 1000w 条数据。

./mysql_random_data_load  acpcanaldb t7 10000000 \
 --host 11.17.6.185 --port 4679 \
 --user=acpcanaldb --password=xxxxxx

数据同步

全量同步 + 增量同步

进入任务管理页面,点击创建任务。选择源实例和目标实例,指定数据库映射关系。image.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.png

高可用测试

CloudCanal 社区版自 1.0.3 开始支持用户添加机器,部署高可用集群。CloudCanal 高可用集群包含如下特性:

  • 任务容灾自动切换:如果任务所在的机器 crash,在机器上的任务会自动切换到集群内其他可用的机器上。
  • 任务手动调度:如果一台机器上运行了过多的任务,支持用户手动调度任务到其他机器上运行。
  • 创建任务时自动分配到低负载机器上:创建任务的时候,任务会自动分配到绑定集群下负载较低的机器上。

CloudCanal 中的 Sidecar 容器负责数据同步,Console 容器负责任务的调度以及为提供管理操作。接下来分别模拟 Sidecar 容器和 Console 容器故障时,数据能否依然正常同步。

模拟 Sidecar 容器故障

目前同步任务运行在 Sidecar 容器 172.18.0.2 上。image.pngimage.pngimage.png

MySQL 主从切换

通常在生产环境中,我们通常会部署双主模式的 MySQL,通过 keepalived 对外提供一个虚拟 IP,当主库发生故障时,虚拟 IP 漂移到备库上,由备库接管服务。关于MySQL 双主高可用部署可以参考 MySQL + Keepalived 双主热备搭建

CloudCanal 使用 binlog + position 进行同步

CloudCanal 默认创建的同步任务是是基于 binlog 和 position 的方式同步的,当 MySQL 发生主从切换时,由于 MySQL 主从的 binlog 文件是不一致的,因此 MySQL 切换后 CloudCanal 基于 binlog + position 的方式无法正常同步数据。

如果想在 MySQL 主从切换后 CloudCanal 可以正常同步数据,需要重新指定 CloudCanal 的位点。先停止 CloudCanal,然后根据 binlog 时间戳回溯位点。image.pngimage.png

使用 GTID 模式同步(推荐)

CloudCanal 使用 GTID 模式同步就可以很好地解决 binlog + position 方式同步时主从切换无法同步数据的问题。GTID 的全称是 global transaction id,表示的是全局事务 ID。

GTID 复制与普通复制最大的区别就是不需要指定二进制文件名和位置,当一个事务在主库端执行并提交时,产生 GTID,一同记录到 binlog 中;binlog 中先记录 GTID,紧跟着再记录事务相关的操作。

当发生 MySQL 主从切换时,在备库上就可以根据 GTID 继续同步数据。使用 GTID 同步的参数需要在创建任务以后在详情中修改,在创建任务时先关闭自动启动任务。image.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.pngimage.png

GET student/_search
#返回结果
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "student",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
          "name" : "marry",
          "id" : 5,
          "age" : 19
        }
      },
      {
        "_index" : "student",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "name" : "jack",
          "id" : 2,
          "age" : 18
        }
      },
      {
        "_index" : "student",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "name" : "mike",
          "id" : 3,
          "age" : 20
        }
      },
      {
        "_index" : "student",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "name" : "cris",
          "id" : 4,
          "age" : 18
        }
      },
      {
        "_index" : "student",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : {
          "name" : "tom",
          "id" : 1,
          "age" : 18
        }
      }
    ]
  }
}

往 MySQL 中再插入 1 条数据。

insert into acpcanaldb.student (name,age) values ('peter',20);

在 Elasticsearch 中也可以查到刚刚删除的数据。

GET student/_search
{
  "query": {
    "match": {
      "name": "peter"
    }
  }
}
#返回结果
{
  "took" : 732,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.6931471,
    "hits" : [
      {
        "_index" : "student",
        "_type" : "_doc",
        "_id" : "6",
        "_score" : 0.6931471,
        "_source" : {
          "name" : "peter",
          "id" : 6,
          "age" : 20
        }
      }
    ]
  }
}

在 MySQL 中删除 age 为 18 的记录。

[email protected] acpcanaldb 01:35:10>select * from acpcanaldb.student;
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  1 | tom   |   18 |
|  2 | jack  |   18 |
|  3 | mike  |   20 |
|  4 | cris  |   18 |
|  5 | marry |   19 |
|  6 | peter |   20 |
+----+-------+------+
6 rows in set (0.01 sec)
[email protected] acpcanaldb 01:36:16>delete from acpcanaldb.student where age=18;
Query OK, 3 rows affected (0.02 sec)
[email protected] acpcanaldb 01:36:27>select * from acpcanaldb.student;
+----+-------+------+
| id | name  | age  |
+----+-------+------+
|  3 | mike  |   20 |
|  5 | marry |   19 |
|  6 | peter |   20 |
+----+-------+------+
3 rows in set (0.01 sec)

在 Elasticsearch 上此时也已经删除了对应的数据。

GET student/_search
{
  "query": {
    "match": {
      "age": 18
    }
  }
}
#返回结果
{
  "took" : 710,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

在 MySQL 中修改表结构。

[email protected] acpcanaldb 01:38:49>update acpcanaldb.student set location='china';
Query OK, 3 rows affected (0.02 sec)
Rows matched: 3  Changed: 3  Warnings: 0
[email protected] acpcanaldb 01:39:25>select * from acpcanaldb.student;
+----+-------+------+----------+
| id | name  | age  | location |
+----+-------+------+----------+
|  3 | mike  |   20 | china    |
|  5 | marry |   19 | china    |
|  6 | peter |   20 | china    |
+----+-------+------+----------+
3 rows in set (0.01 sec)

Elasticsearch 并不会修改对应的 mapping。

GET student/_mapping
#返回结果
{
  "student" : {
    "mappings" : {
      "properties" : {
        "age" : {
          "type" : "integer"
        },
        "id" : {
          "type" : "integer"
        },
        "name" : {
          "type" : "text",
          "analyzer" : "standard"
        }
      }
    }
  }
}

参考资料

  • CloudCanal和Canal的区别
  • CloudCanal社区版高可用部署教程
  • CloudCanal社区版docker版安装(Linux/MacOS)
  • 5分钟搞定 MySQL 到 MySQL "异构"在线数据迁移同步


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
9月前
|
存储 监控 关系型数据库
揭秘:如何构建高效的可视化数据同步平台
杭州奥零数据科技有限公司成立于2023年,专注于数据中台业务,维护开源项目AllData并提供商业版解决方案。AllData提供数据集成、存储、开发、治理及BI展示等一站式服务,支持AI大模型应用,助力企业高效利用数据价值。
揭秘:如何构建高效的可视化数据同步平台
dbMigration .NET 数据同步迁移工具
官网:http://fishcodelib.com/DBMigration.htm
1151 0
|
SQL DataWorks 关系型数据库
DataWorks操作报错合集之如何处理数据同步时(mysql->hive)报:Render instance failed
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
296 0
|
监控 关系型数据库 MySQL
深入了解MySQL主从复制:构建高效稳定的数据同步架构
深入了解MySQL主从复制:构建高效稳定的数据同步架构
382 1
|
canal 消息中间件 关系型数据库
Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
【9月更文挑战第1天】Canal作为一款高效、可靠的数据同步工具,凭借其基于MySQL binlog的增量同步机制,在数据同步领域展现了强大的应用价值
1866 4
|
关系型数据库 MySQL 数据库
【MySQL】手把手教你MySQL数据同步
【MySQL】手把手教你MySQL数据同步
|
消息中间件 NoSQL 关系型数据库
一文彻底搞定Redis与MySQL的数据同步
【10月更文挑战第21天】本文介绍了 Redis 与 MySQL 数据同步的原因及实现方式。同步的主要目的是为了优化性能和保持数据一致性。实现方式包括基于数据库触发器、应用层双写和使用消息队列。每种方式都有其优缺点,需根据具体场景选择合适的方法。此外,文章还强调了数据同步时需要注意的数据一致性、性能优化和异常处理等问题。
2835 0
|
SQL 关系型数据库 MySQL
“震撼揭秘!Flink CDC如何轻松实现SQL Server到MySQL的实时数据同步?一招在手,数据无忧!”
【8月更文挑战第7天】随着大数据技术的发展,实时数据同步变得至关重要。Apache Flink作为高性能流处理框架,在实时数据处理领域扮演着核心角色。Flink CDC(Change Data Capture)组件的加入,使得数据同步更为高效。本文介绍如何使用Flink CDC实现从SQL Server到MySQL的实时数据同步,并提供示例代码。首先确保SQL Server启用了CDC功能,接着在Flink环境中引入相关连接器。通过定义源表与目标表,并执行简单的`INSERT INTO SELECT`语句,即可完成数据同步。
1505 1
|
canal 关系型数据库 MySQL
"揭秘阿里数据同步黑科技Canal:从原理到实战,手把手教你玩转MySQL数据秒级同步,让你的数据处理能力瞬间飙升,成为技术界的新晋网红!"
【8月更文挑战第18天】Canal是一款由阿里巴巴开源的高性能数据同步系统,它通过解析MySQL的增量日志(Binlog),提供低延迟、可靠的数据订阅和消费功能。Canal模拟MySQL Slave与Master间的交互协议来接收并解析Binary Log,支持数据的增量同步。配置简单直观,包括Server和Instance两层配置。在实战中,Canal可用于数据库镜像、实时备份等多种场景,通过集成Canal Client可实现数据的消费和处理,如更新缓存或写入消息队列。
1799 0

热门文章

最新文章