概述
canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费
早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务 trigger 获取增量变更。从 2010 年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。
基于日志增量订阅和消费的业务包括
- 数据库镜像
- 数据库实时备份
- 索引构建和实时维护(拆分异构索引、倒排索引等)
- 业务 cache 刷新
- 带业务逻辑的增量数据处理
当前的 canal 支持源端 MySQL 版本包括 5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x
官方GitHub:
https://github.com/alibaba/canal
工作原理
MySQL主备复制原理
- MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)
- MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
- MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
canal 工作原理
- canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
- MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
- canal 解析 binary log 对象(原始为 byte 流)
单机模式安装
安装前提环境
所需环境 | 本文环境 |
---|---|
linux | centos 7.0 |
jdk | jdk1.8 |
mysql | mysql5.7 |
安装步骤
1.1下载地址
下载tar.gz结尾的压缩包,主要是admin和deployer包,本文演示版本1.1.4;
canal.admin-1.1.4.tar.gz 此为canal的web管理页面,非必须,为了可视化管理
canal.deployer-1.1.4.tar.gz 此为canal的服务器端,核心组件
更多版本参考以下网址:
https://github.com/alibaba/canal/releases
1.2上传linux
利用FTP工具或者linux自带RZ命令,上传压缩包到常用目录(本文上传到/opt/soft目录)
[root@bigdata112 soft]# rz
1.3解压包
在/opt/module目录下,新建canal-admin和canal-server目录,用于存放解压的文件;
[root@bigdata112 module]# mkdir canal-admin
[root@bigdata112 module]# mkdir cana-server
切换到soft目录,然后分别解压两个压缩包到新建canal-admin和canal-server的目录
[root@bigdata112 module]# cd ../soft
[root@bigdata112 soft]# tar -zvxf canal.admin-1.1.4.tar.gz -C /opt/module/canal-admin/
[root@bigdata112 soft]# tar -zvxf canal.deployer-1.1.4.tar.gz -C /opt/module/canal-server/
1.4配置canal-admin环境
释义:canal-admin 为web管理页面,可以通过图形化进行查看和修改,方便快捷。
修改canal-admin/conf/application.yml相关配置(添加注释部分按需要修改)
server:
# 默认端口,可以修改为自己的
port: 8089
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
spring.datasource:
# 若mysql在本机则无需修改,其他机器则写对应ip
address: 127.0.0.1:3306
# canal数据库默认名字,无需修改
database: canal_manager
# 数据库用户名和密码修改
username: root
# 注意密码添加单引号,尤其是有特殊字符时,容易报链接出错
password: 'root'
# 若mysql版本是8以上,则需要改为 com.mysql.cj.jdbc.Driver
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://${spring.datasource.address}/${spring.datasource.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false
hikari:
maximum-pool-size: 30
minimum-idle: 1
canal:
adminUser: admin
adminPasswd: admin
初始化canal数据库
[root@bigdata112 conf]# cd /opt/module/canal-admin/conf
[root@bigdata112 conf]# ll
总用量 24
-rwxrwxrwx. 1 root root 485 3月 12 19:26 application.yml
-rwxrwxrwx. 1 root root 3898 9月 2 2019 canal_manager.sql
-rwxrwxrwx. 1 root root 5123 9月 2 2019 canal-template.properties
-rwxrwxrwx. 1 root root 2036 9月 2 2019 instance-template.properties
-rwxrwxrwx. 1 root root 1568 9月 2 2019 logback.xml
drwxrwxrwx. 3 root root 68 3月 12 19:08 public
[root@bigdata112 conf]# mysql -uroot -proot
mysql> source canal_manager.sql
1.5启动canal-admin服务
[root@bigdata112 canal-admin]# bin/startup.sh
可以查看一下启动日志,如下就代表启动成功:
[root@bigdata112 canal-admin]# tail -f logs/admin.log
2020-03-12 19:38:15.342 [main] INFO o.s.web.servlet.handler.SimpleUrlHandlerMapping - Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2020-03-12 19:38:15.560 [main] INFO o.s.w.s.m.m.annotation.ExceptionHandlerExceptionResolver - Detected @ExceptionHandler methods in customExceptionHandler
2020-03-12 19:38:15.639 [main] INFO o.s.b.a.web.servlet.WelcomePageHandlerMapping - Adding welcome page: class path resource [public/index.html]
2020-03-12 19:38:15.834 [main] INFO o.s.jmx.export.annotation.AnnotationMBeanExporter - Registering beans for JMX exposure on startup
2020-03-12 19:38:15.835 [main] INFO o.s.jmx.export.annotation.AnnotationMBeanExporter - Bean with name 'dataSource' has been autodetected for JMX exposure
2020-03-12 19:38:15.842 [main] INFO o.s.jmx.export.annotation.AnnotationMBeanExporter - Located MBean 'dataSource': registering with JMX server as MBean [com.zaxxer.hikari:name=dataSource,type=HikariDataSource]
2020-03-12 19:38:15.854 [main] INFO org.apache.coyote.http11.Http11NioProtocol - Starting ProtocolHandler ["http-nio-8089"]
2020-03-12 19:38:15.895 [main] INFO org.apache.tomcat.util.net.NioSelectorPool - Using a shared selector for servlet write/read
2020-03-12 19:38:15.919 [main] INFO o.s.boot.web.embedded.tomcat.TomcatWebServer - Tomcat started on port(s): 8089 (http) with context path ''
2020-03-12 19:38:15.923 [main] INFO com.alibaba.otter.canal.admin.CanalAdminApplication - Started CanalAdminApplication in 8.543 seconds (JVM running for 13.991)
或者jps命令查看,出现CanalAdminApplication代表服务启动成功
[root@bigdata112 canal-admin]# jps
2445 CanalAdminApplication
2509 Jps
1.6访问canal-admin测试
由于本机做了hosts映射,192.168.1.112 对应 bigdata112,所以可以在浏览器使用 bigdata112:8089访问:
账号:admin
密码:123456
若想要修改密码,管理页面可以操作修改密码。
1.7开启mysql的binlog
1.7.1 关闭canal-admin服务
[root@bigdata112 canal-admin]# bin/stop.sh
bigdata112: stopping canal 2445 ...
Oook! cost:1
1.7.2 修改mysql的my.cnf文件
查找mysql的my.cnf配置文件位置,并增加开启binlog的配置;
[root@bigdata112 canal-admin]# whereis my.cnf
my: /etc/my.cnf
[root@bigdata112 canal-admin]# vi /etc/my.cnf
[mysqld]
server_id=1
log-bin=mysql-bin
binlog_format=row
1.7.3重启mysql服务并查看配置是否生效
重启并查看配置是否生效,如下显示则代表成功生效;
[root@bigdata112 canal-admin]# systemctl restart mysqld.service
[root@bigdata112 canal-admin]# mysql -uroot -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 3
Server version: 5.7.19-log MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
mysql> show variables like 'binlog_format';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.03 sec)
mysql> show variables like 'log_bin';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_bin | ON |
+---------------+-------+
1 row in set (0.00 sec)
1.7.4 配置canal账户和赋权限
由于本文为mysql5.7,密码策略比较严格,所以进行了相关密码策略的修改,为了创建canal的账户需要,如果mysql版本为5.7以下的,可以直接进行创建用户和赋权操作。
mysql> set GLOBAL validate_password_length=5;
Query OK, 0 rows affected (0.00 sec)
mysql> set global validate_password_number_count=0;
Query OK, 0 rows affected (0.00 sec)
mysql> set global validate_password_mixed_case_count=0;
Query OK, 0 rows affected (0.00 sec)
mysql> set global validate_password_special_char_count=0;
Query OK, 0 rows affected (0.00 sec)
mysql> CREATE USER canal IDENTIFIED BY 'canal';
Query OK, 0 rows affected (0.08 sec)
mysql> GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> show grants for 'canal' ;
+---------------------------------------------------------------------------+
| Grants for canal@% |
+---------------------------------------------------------------------------+
| GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%' |
+---------------------------------------------------------------------------+
1 row in set (0.00 sec)
1.8 启动canal-server服务
开启命令:
[root@bigdata112 canal-admin]# cd ../canal-server/
[root@bigdata112 canal-server]# ll
总用量 8
drwxr-xr-x. 2 root root 72 3月 12 19:10 bin
drwxr-xr-x. 5 root root 4096 3月 12 19:10 conf
drwxr-xr-x. 2 root root 4096 3月 12 19:10 lib
drwxrwxrwx. 2 root root 6 9月 2 2019 logs
[root@bigdata112 canal-server]# bin/startup.sh
关闭命令:
[root@bigdata112 canal-server]# bin/stop.sh
查看是否成功:
[root@bigdata112 canal-server]# jps
2743 CanalLauncher
2777 Jps
出现CanalLauncher进程就代表启动成功了;
OK,单机搭建就到此为止了;
HA高可用模式搭建
三台机器分别为bigdata111,bigdata112,bigdata113,相关软件环境;
bigdata111 | bigdata112 | bigdata113 |
---|---|---|
centos7.0 | centos7.0 | centos7.0 |
jdk1.8 | jdk1.8 | jdk1.8 |
zookeeper3.4 | zookeeper3.4 | zookeeper3.4 |
mysql5.7 | ||
canal-server | canal-server | canal-server |
canal-admin |
由于上面演示了bigdata112的单机安装,则HA的安装在如上基础上进行。
1.分发解压目录
在bigdata112执行scp命令,将bigdata112的canal-server发送到bigdata111,bigdata113服务器。
[root@bigdata112 ~]# scp -r /opt/module/canal-server/ root@bigdata111:/opt/module/
[root@bigdata112 ~]# scp -r /opt/module/canal-server/ root@bigdata113:/opt/module/
2.修改配置
bigdata111配置
在/opt/module/canal-server/conf目录下操作:
[root@bigdata111 canal-server]# cd conf/
[root@bigdata111 conf]# ll
总用量 20
-rwxr-xr-x. 1 root root 291 3月 16 04:43 canal_local.properties
-rwxr-xr-x. 1 root root 5134 3月 16 04:43 canal.properties
drwxrwxrwx. 2 root root 47 3月 16 04:43 example
-rwxr-xr-x. 1 root root 3119 3月 16 04:43 logback.xml
drwxrwxrwx. 2 root root 38 3月 16 04:43 metrics
drwxrwxrwx. 3 root root 4096 3月 16 04:43 spring
[root@bigdata111 conf]# vi canal.properties
#修改zkServers地址
canal.zkServers =bigdata111:2181,bigdata112:2181,bigdata113:2181
#注释file-instance.xml
#canal.instance.global.spring.xml = classpath:spring/file-instance.xml
#开启default-instance.xml
canal.instance.global.spring.xml = classpath:spring/default-instance.xml
修改完毕保存,然后进入example目录,修改instance
[root@bigdata111 conf]# cd example/
[root@bigdata111 example]# ll
总用量 196
-rw-r--r--. 1 root root 196608 3月 16 04:43 h2.mv.db
-rwxr-xr-x. 1 root root 2036 3月 16 04:43 instance.properties
[root@bigdata111 example]# vi instance.properties
# 解开注释,并修改数字,只要保证三台机器这个数字不重复即可
canal.instance.mysql.slaveId=111
# 填写mysql的地址,由于我们装在bigdata112上,所以改为了bigdata112
canal.instance.master.address=bigdata112:3306
bigdata112配置
重复bigdata111的操作步骤,注意将/opt/module/canal-server/conf/example/instance.properties的数字修改一下,同时数据库地址写成主机名或内网IP地址;
canal.instance.mysql.slaveId=112
canal.instance.master.address=bigdata112:3306
bigdata113配置
重复bigdata111的操作步骤,注意将/opt/module/canal-server/conf/example/instance.properties的数字修改一下,同时数据库地址写成主机名或内网IP地址;
canal.instance.mysql.slaveId=113
canal.instance.master.address=bigdata112:3306
3.启动canal-server服务
分别在三台机器启动server服务(若使用的xshell工具,则可以使用右键“发送键输入到所有窗口”一键操作)
[root@bigdata111 canal-server]# bin/startup.sh
[root@bigdata112 canal-server]# bin/startup.sh
[root@bigdata113 canal-server]# bin/startup.sh
jps查看是否启动成功,都出现CanalLauncher代表成功;
[root@bigdata111 canal-server]# jps
3137 Jps
2949 QuorumPeerMain
3115 CanalLauncher
[root@bigdata112 canal-server]# jps
3232 Jps
3025 QuorumPeerMain
3181 CanalLauncher
[root@bigdata113 canal-server]# jps
3193 CanalLauncher
3227 Jps
3036 QuorumPeerMain
在zookeeper上查看节点是否工作,如下则代表成功。
[zk: localhost:2181(CONNECTED) 0] ls /
[zookeeper, yarn-leader-election, hadoop-ha, rmstore, mylock, hbase, otter]
[zk: localhost:2181(CONNECTED) 1] get /otter/canal/destinations/example/running
{"active":true,"address":"192.168.1.112:11111"}
cZxid = 0x1800000023
ctime = Mon Mar 16 05:13:15 CST 2020
mZxid = 0x1800000023
mtime = Mon Mar 16 05:13:15 CST 2020
pZxid = 0x1800000023
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x370dfea0c140001
dataLength = 47
numChildren = 0
查看三台canal机器是否在zookeeper中注册:
[zk: localhost:2181(CONNECTED) 0] ls /
[cluster, controller, brokers, zookeeper, yarn-leader-election, hadoop-ha, admin, isr_change_notification, mylock, log_dir_event_notification, otter, controller_epoch, rmstore, consumers, latest_producer_id_block, config, hbase]
[zk: localhost:2181(CONNECTED) 1] ls /otter/canal/
Command failed: java.lang.IllegalArgumentException: Path must not end with / character
[zk: localhost:2181(CONNECTED) 2] ls /otter
[canal]
[zk: localhost:2181(CONNECTED) 3] ls /otter/canal
[cluster, destinations]
[zk: localhost:2181(CONNECTED) 4] ls /otter/canal/cluster
4.关闭canal
[root@bigdata111 canal-server]# bin/stop.sh
[root@bigdata112 canal-server]# bin/stop.sh
[root@bigdata113 canal-server]# bin/stop.sh
以上则为HA的搭建过程;