(1)Canal入门
1.前言
在我们系统开发过程中,根据业务场景很多数据库数据并不会直接给用户访问的,需要同步保存到ElasticSearch、Redis等存储应用当中(例如最常见的是搜索页面的ElasticSearch数据)。而阿里开源的框架Canal就是做这方面的功能,它可以把数据库(暂时只支持MySQL和Oracle部分版本)日志解析获取增量变更同步到其他存储应用去。
2.什么是Canal?
官网介绍,canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于MySQL数据库增量日志解析,提供增量数据订阅和消费。
从上述介绍我们可以简单认为Canal就是一个简单的增量数据同步工具。
2.1MySQL主备复制原理
根据官网介绍,MySQL主备复制原理如下:
●MySQL master(主库)将数据变更(增删改)写入二进制日志(binary log,其中记录叫做二进制日志事件binary log events,可以通过show binlog events进行查看)。
●MySQL slave(从库)将master的binary log events 拷贝到它的中继日志(relay log)。
●MySQL slave(从库)重放relay log中事件,将数据变更反映它自己的数据。
2.2Canal工作原理
根据官网介绍,Canal工作原理如下图所示:
●canal模拟MySQL slave的交互协议,伪装自己为MySQL slave,向MySQL master发送dump协议。
●MySQL master收到dump请求,开始推送binary log给slave(即canal )。
●canal解析binary log对象(原始为byte流),再推送到MySQL、kafka、ElasticSearch等存储应用当中。
3.Canal能做什么?
早期阿里巴巴因为杭州和美国双机房部署,存在跨机房同步的业务需求,实现方式主要是基于业务trigger(触发器)获取增量变更。从2010年开始,业务逐步尝试数据库日志解析获取增量变更进行同步,由此衍生出了大量的数据库增量订阅和消费业务。所以Canal就是在这个场景中诞生的,它主要作用就是解决基于日志增量订阅和消费的业务,例如:
●数据库镜像。
●数据库实时备份。
●索引构建和实时维护(拆分异构索引、倒排索引等)。
●业务缓存刷新。
●带业务逻辑的增量数据处理(例如ElasticSearch、Redis数据同步)。
在我做过的项目中,cancal经常被用到如下场景:
●根据数据库的数据变更实时更新搜索引擎数据,比如我司电商场景下物料数据发生变更(例如后台上传更新物料信息、价格),实时同步到搜索引擎Elasticsearch上。
●根据数据库的数据变更实时更新缓存,比如专门运营人员每次修改物料品牌信息同时都会同步到Redis上。
●根据数据库的数据变更实时推送到消息队列,比如为了丰富自身系统物料库存,定时作业拉取第三方渠道物料库存推送到RabbitMQ等消息队列去消费入库。
4.如何搭建Canal?
4.1首先得安装个MySQL数据库
如果已经安装好MySQL数据库的,这一步可以跳过,如果没有安装好,请自行安装(也可以查看我之前写过一篇MySQL安装教程,不过个人建议最好还是在Docker上安装,简单方便快捷,如果自己手动安装,不懂点运维基础知识,坑太多了),具体安装教程度娘一堆资料。当前的canal支持MySQL版本包括5.1.x , 5.5.x , 5.6.x , 5.7.x , 8.0.x。
我的MySQL版本是8.0.23,所以canal是支持的。不知道自己安装是什么版本可以通过SELECT VERSION();命令查看。
4.2数据库配置
从上述可知,因为canal是模拟MySQL slave的交互协议,伪装自己为MySQL slave,向MySQL master发送dump协议获取binary log内容对象的,所以需要MySql开启binlog。
●修改mysql.cnf中的配置:
-- 编辑mysql.cnf文件
vim /etc/my.cnf;
-- 在my.cnf上加入如下配置
[mysqld]
log-bin=mysql-bin #开启binlog
binlog-format=ROW #选择ROW模式
server_id=1 #配置MySQL replaction需要定义,不要和canal的slaveId重复
expire-logs-days=10 #binlog日志保留的天数,清除超过10天的日志,防止日志文件过大,导致磁盘空间不足
●授权canal链接MySQL账号具有作为MySQL slave的权限, 如果已有账户可直接grant(我这边是根据官网示例创建一个canal账号来演示):
-- 先登录MySQL
mysql -u root -p
-- 创建用户,用户名:canal,密码:qwer1234
CREATE USER canal IDENTIFIED BY 'qwer1234';
-- 授予上的所有权限给canal用户;
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
-- 刷新权限;
FLUSH PRIVILEGES;
●查看下MySql是否开启binlog日志
是否开启binlog日志:
SHOW VARIABLES LIKE 'log_bin';
查看binlog日志文件列表:
SHOW BINARY LOGS;
查看当前正在写入的binlog文件:
SHOW MASTER STATUS;
4.3Canal配置
安装运行Canal服务端,一定要记得先检查当前Linux系统是否安装了java8环境,如果没有安装启动Canal时候会有如下提示:
[root@dengwu canal]# sh bin/startup.sh
which: no java in (/data/mysql/bin:/data/mysql/lib:/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin)
Cannot find a Java JDK. Please set either set JAVA or put java (>=1.5) in your PATH.
具体安装步骤如下:
●先从Oracle官网下载JDK安装包:
通过Xftp工具导入到预先创建/app/package安装包目录下,再在/usr目录下创建java目录并解压:
mkdir /usr/java
cd /app/package
tar zxvf jdk-8u291-linux-x64.tar.gz -C /usr/java
然后配置java环境变量:
vim /etc/profile
用vim编辑器来编辑profile文件,输入i在文件末尾添加以下内容:
export JAVA_HOME=/usr/java/jdk1.8.0_291
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib:$CLASSPATH
export JAVA_PATH=${JAVA_HOME}/bin:${JRE_HOME}/bin
export PATH=$PATH:${JAVA_PATH}
配置完java环境变量后,:wq保存退出,看看是否生效:
echo $PATH
如果没有生效,让其生效:
source /etc/profile
再瞄瞄java8是否安装成功:
java -version
●然后下载canal, 访问release页面, 选择需要的包下载, 如最新版本1.1.5为例:
可以使用wget工具下载:
wget https://github.com/alibaba/canal/releases/download/canal-1.1.5/canal.deployer-1.1.5.tar.gz
或者手动下载,通过Xftp等工具拉入安装包目录(/app/package)中:
再创建canal安装目录解压安装包:
mkdir /app/canal
cd /app/package
tar zxvf canal.deployer-1.1.5.tar.gz -C /app/canal
然后修改配置:
cd /app/canal
vi conf/example/instance.properties
i
:wq
●启动canal:
cd /app/canal
sh bin/startup.sh
注:Windows使用startup.bat启动
●查看canal进程是否启动成功
ps -ef | grep canal
●查看instance的日志:
vi logs/example/example.log
●关闭canal:
sh bin/stop.sh
●在数据库中查看从库信息:
SHOW SLAVE HOSTS;
查看下canal实例(example)配置是否成功。
●记得把canal端口加入防火墙策略去:
-- 允许通过防火墙
firewall-cmd --permanent --zone=public --add-port=11111/tcp
-- 从防火墙里移除
firewall-cmd --permanent --zone=public --remove-port=11111/tcp
-- 查看端口在防火墙状态
firewall-cmd --permanent --zone=public --query-port=11111/tcp
-- 重启防火墙
firewall-cmd --reload
注:如果是买阿里云服务器,要到阿里云安全组添加允许通过策略。还有Canal Server的默认端口为:11111,若需要修改,可以去/canal/conf目录下的canal.properties配置文件中进行修改。
5.Canal的.NET客户端CanalSharp使用
5.1快速入门
●先安装客户端:
Install-Package CanalSharp
●初始化日志:
CanalSharp使用Microsoft.Extensions.Logging.Abstractions,因为目前主流日志组件,如:nlog、serilog等,全部支持此日志抽象接入,也就是说你可以通过安装nlog、serilog对其的适配,来使用它们,无论是Console App或则是Web App。
var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddFilter("Microsoft", LogLevel.Debug)
.AddFilter("System", LogLevel.Information)
.AddConsole();
});
var logger= loggerFactory.CreateLogger<SimpleCanalConnection>();
●创建连接:
var conn=new SimpleCanalConnection(new SimpleCanalOptions("127.0.0.1",11111,1234),logger);
await conn.ConnectAsync();//连接到Canal Server
await conn.SubscribeAsync();//订阅
●获取数据:
var msg = await conn.GetAsync(1024);
5.2进阶使用
●解析数据
○Entry
上文conn.GetAsync()返回的是一个Entry集合,Entry对应binlog记录,它可能是事务标记也有可能是行数据变化,通过Entry.EntryType来区分,一般事务的标记在业务消费处理时不需要处理。
示例:
var entries = await conn.GetAsync(1024);
foreach (var entry in entries)
{
//不处理事务标记
if (entry.EntryType == EntryType.Transactionbegin || entry.EntryType == EntryType.Transactionend)
{
continue;
}
}
Entry.Header包含了一些binlog以及数据库信息
属性 |
说明 |
Entry.Header.LogfileName |
binlog文件名 |
Entry.Header.LogfileOffset |
binlog偏移 |
Entry.Header.SchemaName |
mysql schema名称 |
Entry.Header.TableName |
表名 |
○RowChange
一般在业务处理中,都会需要行数据的变更,将Entry转换为RowChange对象
示例:
RowChange rowChange = null;
try
{
rowChange = RowChange.Parser.ParseFrom(entry.StoreValue);
}
catch (Exception e)
{
_logger.LogError(e);
}
通过RowChange.EventType来Row是什么变化,Update、Delete和Insert对应sql中的update、delete和insert语句,通过RowChange.RowDatas属性,来访问RowChange对象中包含的行变化数据集合。示例,遍历 RowChange 中的行数据:
foreach (var rowData in rowChange.RowDatas)
{
//删除的数据
if (eventType == EventType.Delete)
{
PrintColumn(rowData.BeforeColumns.ToList());
}
//插入的数据
else if (eventType == EventType.Insert)
{
PrintColumn(rowData.AfterColumns.ToList());
}
//更新的数据
else
{
_logger.LogInformation("-------> before");
PrintColumn(rowData.BeforeColumns.ToList());
_logger.LogInformation("-------> after");
PrintColumn(rowData.AfterColumns.ToList());
}
} private static void PrintColumn(List<Column> columns)
{
foreach (var column in columns)
{
Console.WriteLine($"{column.Name} : {column.Value} update= {column.Updated}");
}
}
○Column
Column如其名,代表数据库中表的每一列的信息。
属性名 |
说明 |
Column.Name |
列名 |
Column.Value |
列的值 |
Column.Updated |
列是否被更新 |
5.3应答机制
应答机制可以保证消费数据的准确性,Canal服务端会记录Client消费的进度,需要客户端发送ACK消息,服务端才会更新进度。类似于在消息队列中的ACK机制,如RabbitMQ。
●自动应答
await conn.GetAsync(1024);//获取数据并自动应答
GetAsync()会在获取数据后,自动向Server发送ack消息。
●手动应答
var msg = await conn.GetWithoutAckAsync(1024);//获取数据
await conn.AckAsync(msg.Id);//手动应答
await conn.RollbackAsync(msg.Id);//回滚
5.4高可用
这里的高可用分为两类,客户端集群和服务端集群。都是采用冷备模式,因为对于binlog数据消费来说,并行处理将会带来数据顺序错乱的问题,当然你可以通过一些复杂的机制去实现,这里不做说明。集群部署需要Zookeeper组件。
●服务端集群
在conf/canal.properties文件中修改zookeeper地址:
canal.zkServers=127.0.0.1:2181
集群中每个实例需,配置相同的zookeeper地址。
●客户端集群
客户端集群和服务端集群采用相同的模式,每个实例去抢占锁,获得了锁那么这个实例就运行获取数据,其他实例做冷备。若正在运行消费数据的实例由于网络波动,导致和zookeeper失去连接,那么其他客户端实例不会立即抢占,会等待60s后才执行抢占,给与这个实例恢复的机会。
客户端集群使用的连接对象和快速入门中的不同:ClusterCanalConnection,但使用方法基本相同。
示例:
//初始化日志
var loggerFactory = LoggerFactory.Create(builder =>
{
builder
.AddFilter("Microsoft", LogLevel.Debug)
.AddFilter("System", LogLevel.Information)
.AddConsole();
});
var logger = loggerFactory.CreateLogger<Program>();
//设置zk地址和clientid,统一集群的client必须相同
var conn = new ClusterCanalConnection( new ClusterCanalOptions("localhost:2181", "12350")
//连接到Server loggerFactory);
await conn.ConnectAsync();
//订阅
await conn.SubscribeAsync();
await conn.RollbackAsync(0);
while (true)
{
try
{
//获取数据
var msg = await conn.GetAsync(1024);
}
catch (Exception e)
{
_logger.LogError(e,"Error.");
//发生异常执行重连,此方法只有集群连接对象才有
await conn.ReConnectAsync();
}
}
5.5订阅
订阅指过滤表(table)的规则,Canal客户端发送给客户端订阅规则,那么服务端将会推送符合规则的表数据过来,采用正则匹配。
允许所有表:.\*\\\\..\*
6.小结
这里这是简单介绍Canal工作原理,能做什么,还有.NET客户端CanalSharp使用,其实Canal涉及知识点还是很多的,例如配置MQ模式、服务集群、Web管理界面部署,多实例等等。后面如果有时间,我还会继续花时间去学习。
参考文献:
CanalSharp文档
CanalSharp
(1)Canal入门的更多相关文章
- canal入门Demo
关于canal具体的原理,以及应用场景,可以参考开发文档:https://github.com/alibaba/canal 下面给出canal的入门Demo (一)部署canal服务器 可以参考官方文 ...
- canal 入门(基于docker)
第一步:安装MySQL:(可以参考:https://my.oschina.net/amhuman/blog/1941540) 命令: sudo docker run -it -d --restart ...
- canal 入门
参考文章:Canal - 安装 https://www.aliyun.com/jiaocheng/1131288.html?spm=5176.100033.2.7.7b422237XAirIe 前 ...
- canal入门使用
1.下载canal安装包: 地址:https://github.com/alibaba/canal/releases 图例: 2.将下载好的安装包复制到Linux,解压 3.修改配置文件 vi con ...
- Canal入门
配置mysql 1.mysql开启binlog mysql默认没有开启binlog,修改mysql的my.cnf文件,添加如下配置,注意binlog-format必须为row,因为binlog如果为S ...
- 数据的异构实战(一) 基于canal进行日志的订阅和转换
什么是数据的异构处理.简单说就是为了满足我们业务的扩展性,将数据从某种特定的格式转换到新的数据格式中来. 为什么会有这种需求出现呢? 传统的企业中,主要都是将数据存储在了关系型数据库中,例如说MySQ ...
- 使用canal分析binlog(一) 入门
canal介绍 canal是应阿里巴巴存在杭州和美国的双机房部署,存在跨机房同步的业务需求而提出的.早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求.不过早期的数据库同步 ...
- canal 结合 kafka 入门
1.kafka的安装: 略 2.cannal 配置 使用卡夫卡: 修改 /home/admin/canal-server/conf/canal.properties 2.1 修改canal.ser ...
- 「从零单排canal 01」 canal 10分钟入门(基于1.1.4版本)
1.简介 canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据 订阅 和 消费.应该是阿里云DTS(Data Transfer Servi ...
随机推荐
- centos7安装es6.4.0
一.首先进入到opt文件夹cd opt二.然后下载es安装包wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearc ...
- margin (子元素远离父元素边框)
如果父盒子没有设置border框着,那么他的子元素无法利用margin-top 来远离父元素的上边框 如果使用了margin-top会使子元素和父元素一起往下移 (子想离,父不设置border边框 则 ...
- [项目] 淘淘商城 Part.1
电商 市场 2013:79万笔/分钟 2014:13.4万亿,双11支付宝交易峰值285万笔/分钟 2015:50万亿 技术特点 一个Tomcat:500并发 分布式:上万并发 高并发.集群.负载均衡 ...
- linux进阶之yum管理
一.部署私有repo源 1.官网下载需要的仓库: rsync -avrt --delete rsync://mirrors.ustc.edu.cn/centos/7/cloud/x86_64/open ...
- UCOS 多任务系统中需要注意的地方 一个任务至少要有一些执行内容
图片说明: 在一个TASK的最外层FOR();中 如果有调用BREAK会怎样??
- LTC4020
今天凯哥说他之前有一块电池放电低于20V了 然后接上4020后 会先浮充 涓流充 大约200ma 充过了20V后又是4A了
- STM32低功耗总结
之前自己做过一个项目的低功耗大约11ua,那时总结下有几点: 1.外设时钟必须切换为内部时钟: 2.不用的外设全部关闭,要用再开就是了: 3.浮空引脚必须配置为下拉: 4.硬件上的上拉.下拉电阻切记不 ...
- 通过git将项目传到github上
lenovo@LAPTOP-3KMEN0B2 MINGW64 /e/Users/lenovo/springboot-project/forum $ ls forum.iml HELP.md mvnw* ...
- Tomcat 中文乱码
问题描述 tomcat9启动后会有中文乱码,比如控制台乱码: startup.bat启动时乱码: 解决方法 打开"/apache-tomcat-9.0.20/conf/logging.pro ...
- 初遇SpringBoot踩坑与加载静态文件遇到的坑
SpringBoot开发 创建SpringBoot项目 大家都知道SpringBoot开发非常快,创建SpringBoot项目时,勾上SpringW ...