Canal:部署CanalCanal Admin & 使用ZooKeeper进行集群管理
Posted ITKaven
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Canal:部署CanalCanal Admin & 使用ZooKeeper进行集群管理相关的知识,希望对你有一定的参考价值。
简介
以下关于Canal
的介绍来自Github官方介绍。
canal [kə'næl]
,译意为水道/管道/沟渠,主要用途是基于mysql
数据库增量日志解析,提供增量数据订阅和消费。
工作原理
canal
模拟MySQL slave
的交互协议,将自己伪装为MySQL slave
,向MySQL master
发送dump
协议。MySQL master
收到dump
请求,开始推送binary log
给slave
(即canal
)。canal
解析binary log
对象(原始为byte
流)。
因此可以使用Canal
来提供MySQL
数据库增量数据的订阅和消费,当MySQL
数据库中的数据发生变化时,Canal
可以高效地将这些数据同步到下游服务,比如更新Redis
中的数据、提供数据给ElasticSearch
以及更新索引异构表等。
架构
说明:
server
代表一个canal
运行实例,对应于一个jvm
。instance
对应于一个数据队列 (1
个server
对应1-n
个instance
)。
instance
模块:
eventParser
(数据源接入,模拟slave
协议和master
进行交互,协议解析)。eventSink
(Parser
和Store
的链接器,进行数据过滤、加工以及分发的工作)。eventStore
(数据存储)。metaManager
(增量订阅和消费信息管理器)。
环境准备
本篇博客将介绍如何部署Canal
以及Canal Admin
,而它们的依赖环境必须要提取准备好。
- 安装
Mysql
:需要先安装Mysql
,博主这里安装Mysql 8
(Mysql 8 - CentOS yum & Docker安装Mysql 8),使用CentOS yum
方式安装即可,其他操作系统的安装步骤可自行百度。
设置开机自启动并且立即启动Mysql
:systemctl enable mysqld & systemctl start mysqld
,查询Mysql
状态:systemctl status mysqld
,状态为active (running)
即可。
- 安装
JDK
:还需要配置JDK
环境(JDK8下载地址),下载好压缩包后,使用Xftp
将该压缩包上传到虚拟机中。
解压文件(tar -zxvf jdk-8u202-linux-x64.tar.gz
)以及修改/etc/profile
配置文件(vim /etc/profile
,没有vim
可以执行yum install -y vim
进行安装)。这些常用工具的配置还是要自己去理解以及多练习,敲熟了,比搜索加Copy
快多了(export JAVA_HOME=/usr/local/jdk1.8.0_202
、export CLASSPATH=.:$JAVA_HOME/lib
、export PATH=$JAVA_HOME/bin:$PATH
)。
使对/etc/profile
配置文件的修改生效(source /etc/profile
)。
进入Mysql
创建Canal
和Canal Admin
需要使用的用户,并且授予该用户权限。
create user kaven identified by 'kaven';
- Mysql 8 - CentOS yum & Docker安装Mysql 8,这篇博客有介绍如何进入
Mysql 8
(需要获取初始密码进入)、修改root
用户的密码以及修改合法密码的校验规则,不然给用户设置这种弱密码(kaven
)Mysql 8
会报错。
授予用户权限(为了方便,博主这里直接授予用户所有权限,可以根据目前的业务需求来设置):
grant all privileges on *.* to 'kaven'@'%';
flush privileges;
还需要修改Mysql
的配置(vim /etc/my.cnf
),要先开启binlog
写入功能,配置binlog-format
为ROW
模式,my.cnf
需要增加的配置如下所示:
[mysqld]
log-bin=mysql-bin # 开启 binlog
binlog-format=ROW # 选择 ROW 模式
server_id=1 # 配置 MySQL replaction 需要定义,不要和 canal 的 slaveId 重复
重启Mysql
:
systemctl restart mysqld
部署Canal
博主这里选择1.1.5
版本(Canal Admin
要求Canal
版本>=1.1.4
,需要依赖canal-server
提供面向admin
的动态运维管理接口),下载下图所示的两个压缩包。
下载好后再将它们上传到虚拟机中。Canal
对应于canal.deployer
项目,Canal Admin
对应于canal.admin
项目。先解压canal.deployer
压缩包,再修改配置,如果Canal
和Canal Admin
不在同一台主机上部署(博主这里是部署在同一台主机上),需要修改Canal
的配置(conf/canal_local.properties
)。
[root@localhost local]# mkdir ./canal-server
[root@localhost local]# tar -zxvf canal.deployer-1.1.5.tar.gz -C ./canal-server
[root@localhost local]# cd canal-server/
[root@localhost canal-server]# vim conf/canal_local.properties
配置修改如下图所示:
等启动Canal Admin
之后再启动Canal
。
部署Canal Admin
Canal Admin
设计上是为Canal
提供整体配置管理、节点运维等面向运维的功能,提供相对友好的WebUI
操作界面,方便更多用户快速和安全的操作。
解压文件和修改配置:
[root@localhost canal-server]# cd /usr/local/
[root@localhost local]# mkdir ./canal-admin
[root@localhost local]# tar -zxvf canal.admin-1.1.5.tar.gz -C ./canal-admin/
[root@localhost local]# cd canal-admin/
[root@localhost canal-admin]# vim conf/application.yml
修改数据库相关配置,需要适配Mysql 8
。
Mysql 8
的驱动类名是com.mysql.cj.jdbc.Driver
,并且Mysql 8
需要配置serverTimezone
(以下serverTimezone
配置都可以)。
serverTimezone=GMT%2B8
serverTimezone=GMT
serverTimezone=Asia/Shanghai
如果用户使用了sha256_password
认证,密码在传输过程中必须使用TLS
协议保护,如果RSA
公钥不可用,可以使用服务器提供的公钥;可以在连接中通过ServerRSAPublicKeyFile
指定服务器的RSA
公钥,或者使用allowPublicKeyRetrieval=true
参数以允许客户端从服务器获取公钥;但是需要注意的是allowPublicKeyRetrieval=true
可能会导致恶意的代理通过中间人攻击(MITM
)获取到明文密码,所以默认是关闭的,必须显式开启。
Mysql 8
的密码加密方式为caching_sha2_password
,将其修改为mysql_native_password
,就可以不需要allowPublicKeyRetrieval=true
参数。
alter user 'kaven'@'%' identified with mysql_native_password by 'kaven';
flush privileges;
还要将Canal Admin
项目中的sql
文件导入Mysql
中(会生成用于管理Canal
的相关表)。
[root@localhost canal-admin]# mysql -uroot -p
Enter password:
mysql> source conf/canal_manager.sql
Query OK, 1 row affected, 2 warnings (0.06 sec)
Database changed
...
Query OK, 0 rows affected (0.00 sec)
mysql> exit
Bye
还需要更换Mysql
连接jar
包,可以在本地maven
仓库里面找,博主选择平时用的最新的8.0.22
版本。
使用下面这条命令来查看Mysql
版本:
select version();
博主这里的Mysql
版本是8.0.27
。
默认的Mysql
连接jar
包是5.1.48
版本,连接Mysql 8
会出问题。
[root@localhost canal-admin]# cd lib
[root@localhost lib]# ll
删除该jar
包。
[root@localhost lib]# rm -f mysql-connector-java-5.1.48.jar
使用Xftp
上传Mysql 8
的连接jar
包到Canal Admin
项目的lib
路径下。
[root@localhost lib]# find ./ -name mysql*
./mysql-connector-java-8.0.22.jar
启动Canal Admin
。
[root@localhost lib]# cd ..
[root@localhost canal-admin]# sh bin/startup.sh
查看日志,发现日志文件不存在,说明启动失败了。
[root@localhost canal-admin]# tail logs/admin.log
tail: 无法打开"logs/admin.log" 读取数据: 没有那个文件或目录
在bin
目录下可以找到类似hs_err_pid20182.log
的日志文件。
[root@localhost canal-admin]# cd bin
[root@localhost bin]# ll
总用量 40
-rw-r--r--. 1 root root 6 12月 13 23:45 admin.pid
-rw-r--r--. 1 root root 18584 12月 13 23:45 hs_err_pid20182.log
-rwxr-xr-x. 1 root root 205 4月 19 2021 restart.sh
-rwxr-xr-x. 1 root root 747 4月 19 2021 startup.bat
-rwxr-xr-x. 1 root root 2047 4月 19 2021 startup.sh
-rwxr-xr-x. 1 root root 1362 4月 19 2021 stop.sh
由下图可知,Canal Admin
启动失败是由于分配2G
内存不成功导致的(因为虚拟机本身内存就只分配了2G
)。
因此需要修改项目的JVM
堆内存配置,这个配置在启动脚本中设置。
[root@localhost bin]# vim startup.sh
初始堆内存和最大堆内存都设置成1G
。
再启动Canal Admin
。
[root@localhost bin]# ./startup.sh
再查看日志,如下图所示,说明启动成功了。
启动成功后,再关闭防火墙,让本地可以访问Canal Admin
。
[root@localhost bin]# systemctl stop firewalld
本地访问192.168.1.199:8089
。
现在可以启动Canal
了。
[root@localhost bin]# cd /usr/local/canal-server
[root@localhost canal-server]# sh bin/startup.sh local
查看日志,检查Canal
是否启动成功。
[root@localhost canal-server]# vim logs/canal/canal.log
如下图所示,说明启动成功了。
Server & Instance
刚刚启动的server
(Canal
)已经在Canal Admin
上显示出来了,并且状态是启动。
可以对server
进行操作。
比如查看server
的日志。
新建instance
。
如下图所示进行操作即可。
example instance
也是启动状态。
可以查看example instance
的日志。
再新建一个other instance
,配置和example instance
一样,other Instance
的状态也是启动。
也可以查看other instance
的日志。
实现逻辑就是在Canal
项目的日志路径和配置路径下创建了对应instance
的相关文件。
[root@localhost canal-server]# ll logs
总用量 0
drwxr-xr-x. 2 root root 47 12月 14 15:27 canal
drwxr-xr-x. 2 root root 25 12月 14 15:20 example
drwxr-xr-x. 2 root root 23 12月 14 15:34 other
[root@localhost canal-server]# ll conf
总用量 16
-rwxrwxrwx. 1 root root 319 4月 19 2021 canal_local.properties
-rwxrwxrwx. 1 root root 6277 4月 19 2021 canal.properties
drwxrwxrwx. 2 root root 65 12月 14 15:17 example
-rwxrwxrwx. 1 root root 3437 4月 19 2021 logback.xml
drwxrwxrwx. 2 root root 39 12月 13 23:02 metrics
drwxr-xr-x. 2 root root 38 12月 14 15:36 other
drwxrwxrwx. 3 root root 149 12月 13 23:02 spring
[root@localhost canal-server]# ll conf/other/
总用量 156
-rw-r--r--. 1 root root 155648 12月 14 15:36 h2.mv.db
-rw-r--r--. 1 root root 40 12月 14 15:36 meta.dat
example instance
的相关文件在Canal
项目中默认存在,而配置信息以在Canal Admin
中的配置为准(其他instance
也一样),比如修改example instance
的数据库用户配置。
example instance
的日志中就会出现数据库拒绝访问的错误日志。
因此instance
的配置以Canal Admin
中的配置为准。
集成ZooKeeper
搭建ZooKeeper
可以参考下面这几篇博客:
启动ZooKeeper
并且关闭防火墙。
[root@localhost ~]# cd /usr/local/apache-zookeeper-3.6.3-bin/
[root@localhost apache-zookeeper-3.6.3-bin]# sh bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/local/apache-zookeeper-3.6.3-bin/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@localhost apache-zookeeper-3.6.3-bin]# sh bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/local/apache-zookeeper-3.6.3-bin/bin/../conf/zoo.cfg
Client port found: 9000. Client address: localhost. Client SSL: false.
Mode: standalone
[root@localhost apache-zookeeper-3.6.3-bin]# systemctl stop firewalld
在Canal Admin
上添加集群,集群名称为zookeeper
。
修改zookeeper
集群的主配置。
主要是添加ZooKeeper
服务地址。
在zookeeper
集群下创建server
(博主把之前创建的instance
和server
都删除了,因为server
不能修改所属集群配置,只能删除再重新创建)。
创建kaven server
成功,状态为启动。
在zookeeper
集群下创建instance
。
由下图所示,itkaven instance
由zookeeper
集群下的kaven server
运行,状态也是启动。
查看itkaven instance
的日志,很显然启动成功了。
因为zookeeper
集群下只有一个server
,即kaven server
,因此itkaven instance
肯定是在kaven server
上运行的。查看Canal
项目(zookeeper
集群下唯一的server
)的日志文件和配置文件即可发现itkaven instance
的相关文件:
[root@localhost canal-server]# ll logs
总用量 0
drwxr-xr-x. 2 root root 47 12月 14 15:27 canal
drwxr-xr-x. 2 root root 25 12月 14 15:20 example
drwxr-xr-x. 2 root root 25 12月 14 16:26 itkaven
drwxr-xr-x. 2 root root 23 12月 14 15:34 other
[root@localhost canal-server]# ll conf
总用量 16
-rwxrwxrwx. 1 root root 319 4月 19 2021 canal_local.properties
-rwxrwxrwx. 1 root root 6277 4月 19 2021 canal.properties
drwxrwxrwx. 2 root root 65 12月 14 16:05 example
drwxr-xr-x. 2 root root 38 12月 14 16:27 itkaven
-rwxrwxrwx. 1 root root 3437 4月 19 2021 logback.xml
drwxrwxrwx. 2 root root 39 12月 13 23:02 metrics
drwxr-xr-x. 2 root root 38 12月 14 15:36 other
drwxrwxrwx. 3 root root 149 12月 13 23:02 spring
ZooKeeper
中也会保存一些数据(比如集群下的所有server
和instance
信息,以及instance
在哪个server
上运行)。
[root@localhost apache-zookeeper-3.6.3-bin]# sh bin/zkCli.sh -timeout 5000 -server 127.0.0.1:9000
[zk: 127.0.0.1:9000(CONNECTED) 0] ls -R /otter
/otter
/otter/canal
/otter/canal/cluster
/otter/canal/destinations
/otter/canal/cluster/192.168.1.199:11111
/otter/canal/destinations/itkaven
/otter/canal/destinations/itkaven/cluster
/otter/canal/destinations/itkaven/running
/otter/canal/destinations/itkaven/cluster/192.168.1.199:11111
[zk: 127.0.0.1:9000(CONNECTED) 1] get /otter/canal/destinations/itkaven/running
"active":true,"address":"192.168.1.199:11111"
HA机制设计
canal
的HA
分为两部分,canal server
和canal client
分别有对应的HA
实现:
canal server
: 为了减少对mysql dump
的请求,不同server
上的instance
要求同一时间只能有一个处于running
,其他的处于standby
状态。canal client
: 为了保证有序性,一个instance
同一时间只能由一个canal client
进行get/ack/rollback
操作,否则客户端接收无法保证有序。
整个HA
机制的控制主要是依赖了ZooKeeper
的几个特性,watcher
和EPHEMERAL
节点(和session
生命周期绑定)。
大致步骤:
canal server
要启动某个canal instance
时,都先向ZooKeeper
进行一次尝试启动判断 (创建EPHEMERAL
节点,谁创建成功就允许谁启动)。- 创建
ZooKeeper
节点成功后,该canal server
就启动对应的canal instance
,没有创建成功的canal instance
就会处于standby
状态。 - 一旦
ZooKeeper
发现canal server
创建的节点消失后,立即通知其他的canal server
再次进行步骤1
的操作,重新选出一个canal server
启动canal instance
。 canal client
每次进行connect
时,会首先向ZooKeeper
询问当前是谁启动了canal instance
,然后和其建立连接,一旦连接不可用,会重新尝试connect
。
canal client
的方式和canal server
的方式类似,也是利用ZooKeeper
抢占EPHEMERAL
节点的方式进行控制。
部署Canal
、Canal Admin
以及使用ZooKeeper
进行集群管理就介绍到这里,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。
以上是关于Canal:部署CanalCanal Admin & 使用ZooKeeper进行集群管理的主要内容,如果未能解决你的问题,请参考以下文章