Canal 的 GitHub 地址:alibaba/canal: 阿里巴巴 MySQL binlog 增量订阅&消费组件 (github.com)
canal 译为管道,是阿里巴巴旗下的一款开源项目,纯 Java 语言开发。基于 数据库增量日志解析,提供增量数据订阅和消费。
canal 作为数据同步的工具,它运用了 MySQL 的主从复制的原理,接下来跟随 canal 官网的描述,来回顾 MySQL 主从复制是什么。
MySQL 集群一般分为 一个 master 主节点 和 若干个 slave 从节点。
MySQL Master 主节点: 将数据变更记录写入 Binary Log(二进制日志)中,这日志里的记录称为 Binary Log Events ,即 二进制日志事件。
MySQL Slave 从节点 则将 Master 的 Binary Log Events 拷贝到 自身的中继日志(Relay Log)中
MySQL Slave 重新实现 Relay Log 里的事件,将数据变更成自己的数据,从而实现复制了主节点的数据。
网上的示意图:
在大致了解 MySQL 主从复制后,我们继续了解 canal 的工作原理:
缩短成一句话就是:
Canal 模拟成 MySQL 主从复制过程里的 Slave 从节点,向 MySQL Master 主节点发送 dump 协议的请求,然后 Master 就会老实地传回一个 二进制日志对象,Canal可以根据这个日志对象来复刻 MySQL Master 里的数据。
运行环境:
Canal 原理是基于 MySQL 主从复制的,通过 dump 协议向 Master 发送请求,所以我们要先确保 MySQL 开启了 Binary Log 的功能,否则是无法进行数据同步的。
1)安装 Docker
sudo apt-get install docker.io
建议切换 Docker 镜像源为国内的,这样下载速度会比较快,网上有很多教程,这里就不记录了。
2)拉取 Docker 镜像站的 MySQL 镜像
sudo docker pull mysql:5.7
3)Docker 根据镜像创建容器,并设置容器卷
sudo docker run -d --name mysql \
--privileged=true \
-p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
参数说明:
-d 表示创建则部署
-- name 指定容器的名称
-e 则是环境配置,这里设置数据库密码为 123456
-p 表示端口的映射,设置宿主机指定的端口映射到容器中的端口,这里用于连接MySQL。
4)查看当前运行的 Docker 容器
# 查看正在运行的容器
sudo docker ps
# 查看所有的容器
sudo docker ps -a
Docker 常用命令:
1. 查看容器 ID, 结果中 CONTAINER ID 那一列则为容器的ID
docker ps -a
2. 关闭容器
docker stop 容器ID
3. 重启容器
docker restart 容器ID
4. 查看容器启动日志
docker logs [OPTIONS] 容器ID
[OPTIONS] 可选参数有
--details 显示更多的信息
-f 跟踪实时日志
--since [] 显示自某个timestamp之后的日志,或相对时间,如40m(即40分钟)
--tail [] 从日志末尾显示多少行日志, 默认是 all
-t,显示时间戳
5. 删除容器
docker rm 容器ID
6. 进入容器
docker exec -it 容器ID bash
使用 Navicat 远程连接 虚拟机 Docker 容器的 MySQL,通过虚拟机IP和 3306 端口即可连接,使用 MySQL Shell 后,可通过命令来检查是否开启了 Binary Log 功能(5.7 版本是默认关闭的):
show variables like 'log_bin';
如果返回结果是 OFF,则没有开启这个日志功能:
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | OFF |
+---------------+-------+
1 row in set (0.02 sec)
接下来开始进行配置,**需要进入到 Docker 容器 **添加 MySQL 的配置文件 my.cnf(由于初学 Docker,暂时不用Docker 的容器卷),执行下面的命令:(由于Docker 的MySQL 容器是不自带 文本编辑器的,所以可以通过原始的 touch 命令创建文件, echo输出 和 >> 文件流写入内容到文件。
(进入 Docker 容器可参考上面的常用命令,进入后再执行下面的命令)
cd /etc/mysql
touch my.cnf
echo '[mysqld]' >> my.cnf
echo 'log-bin=mysql-bin' >> my.cnf
echo 'binlog_format=ROW' >> my.cnf
echo 'server-id=1' >> my.cnf
cat my.cnf
exit
配置说明:
log-bin 指定 binlog 的文件名
binlog_format 指定 binlog 的模式
service_id 指定当前 MySQL 的实例 id, 不能和 canal 的相同
重启容器
sudo docker restart 容器ID
重启后再次使用 Navicat 连接 数据库,查看是否开启了 binlog ,显示 ON 即可。
show variables like 'log_bin';
除了开启binlog外,我们需要添加用户和对应的权限,用于 canal 登录
CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';
GRANT SHOW VIEW, SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;
创建测试的数据库和数据表,Docker 容器里创建, 本地 Windows 也创建。
CREATE DATABASE testDB;
use testDB;
CREATE TABLE `testTable`(
id varchar(255),
name varchar(255)
) ENGINE = InnoDB CHARACTER SET = 'utf8';
INSERT INTO testTable(id, name) values (1, 'a');
SELECT * FROM testTable;
Canal 的安装版本可查看 Github 上 Canal 的 Release 发行版本:Releases · alibaba/canal (github.com)
这里我直接下载最新的1.1.6 版本 到 Ubuntu 系统中:
sudo wget https://github.com/alibaba/canal/releases/download/canal-1.1.6-hotfix-1/canal.deployer-1.1.6.tar.gz
下载速度比较慢的可以试试我分享的网盘链接:
链接:https://pan.baidu.com/s/1mXmkDUXDt-I5Pr5pWy_KVQ
提取码:p9cb
解压压缩包
mkdir canal
tar -zxvf ./canal.deployer-1.1.6.tar.gz -C ./canal
配置文件在 Canal 压缩后目录下的 conf / example / instance.properties
配置内容为:
# canal 的 节点ID, 不能和 MySQL Master的节点ID相同
canal.instance.mysql.slaveId=0
# 数据库连接地址
canal.instance.master.address=192.168.152.129:3306
# 数据库用户名和密码
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
# 数据库表的匹配规则, 支持正则表达式, 这里指定为testDB里的表testTable
canal.instance.filter.regex=testDB.testTable
canal 操作相关脚本在解压目录的 bin 文件夹
这里直接启动即可(canal 运行需要有 JDK 环境,这里推荐使用 JDK 8)
启动后通过 JPS 命令查看是否有 CanalLauncher
进程,有则启动成功
项目结构:
|- canal-client
|———|- src
|——————|- main
|—————————|- java
|————————————|- com.ge.canal
|——————————————|- client
|————————————————|- CanalClient.java
|——————————————|- CanalApplication.java
|—————————|- resources
|——————————————|- application.properties
引入 Maven 依赖;
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.2.1.RELEASEversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>canal