使用canal实现数据实时同步

本文介绍了Canal,阿里巴巴的一款开源数据库增量订阅和消费工具,基于MySQLbinlog技术,用于实时同步数据库变化,降低微服务间数据耦合。详细讲解了Canal的原理、配置和在统计分析中的应用案例。

canal
在这里插入图片描述

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

工作原理
在这里插入图片描述

  • MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log
    events,可以通过 show binlog events 进行查看)

  • MySQL slave 将 master 的 binary
    log events 拷贝到它的中继日志(relay log) MySQL slave 重放 relay log

  • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
    canal工作原理

  • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
    canal工作原理

  • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )

  • canal 解析 binary log 对象(原始为 byte 流)

我自己的应用场景是在统计分析功能中,采用了微服务调用的方式获取统计数据,但是这样耦合度很高,效率相对较低,我现在采用Canal数据库同步工具,通过实时同步数据库的方式实现,例如我们要统计每天注册与登录人数,我们只需要把会员表同步到统计库中,实现本地统计就可以了,这样效率更高,耦合度更低。
Canal是阿里巴巴旗下的一款开源项目,纯Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。

Canal环境搭建
canal的原理是基于mysql binlog技术,所以这里要开启mysql的binlog写入功能
在linux系统中,开启mysql服务:systemctl start mysqld或者service mysql start

检查binlog功能是否开启
在这里插入图片描述
开启binlog功能
如果显示状态为OFF表示该功能尚未开启,开启binlog功能

修改mysql的配置文件my.cnf

vim /etc/my.cnf

追加内容

log-bin=mysql-bin     #binlog文件名
binlog_format=ROW     #选择row模式
server_id=1           #mysql实例id,不能和canal的slaveId重复

在这里插入图片描述

重启mysql

systemctl restart mysqld

再次登录mysql客户端,查看log_bin变量
在这里插入图片描述
显示为ON表示该功能已开启。

在mysql里面添加以下的相关用户和权限

CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';
GRANT SHOW VIEW, SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
FLUSH PRIVILEGES;

这其实是添加了能远程访问mysql数据库的用户,账号和密码都是canal,由于我的虚拟机本来就添加过root用户,这里我就不再添加这个canal了,你根据自己情况。

下载安装Canal服务
下载canal地址

下载之后,放到目录中,解压文件
在这里插入图片描述
解压

tar zxvf canal.deployer-1.1.4.tar.gz -C /usr/local/canal/

在这里插入图片描述
修改配置文件

vim conf/example/instance.properties

在这里插入图片描述

这里是引用注: mysql 数据解析关注的表,Perl正则表达式. 多个正则之间以逗号(,)分隔,转义符需要双斜杠()
1.常见例子:所有表:.* or .\…
2.canal schema下所有表: canal\…*
3.canal下的以canal打头的表:canal\.canal.*
4…canal schema下的一张表:canal.test1
5.多个规则组合使用:canal\…*,mysql.test1,mysql.test2 (逗号分隔) 注意:此过滤条件只针对row模式的数据有效(ps.
6.mixed/statement因为不解析sql,所以无法准确提取tableName进行过滤)

进入bin目录下启动

./startup.sh

在这里插入图片描述
代码整合 创建canal_client模块

引入相关依赖

创建application.properties配置文件

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>

    <dependency>
        <groupId>commons-dbutils</groupId>
        <artifactId>commons-dbutils</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>

    <dependency>
        <groupId>com.alibaba.otter</groupId>
        <artifactId>canal.client</artifactId>
    </dependency>
</dependencies>
# 服务端口
server.port=10000
# 服务名
spring.application.name=canal-client

# 环境设置:dev、test、prod
spring.profiles.active=dev

# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123456

编写canal客户端类

import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.protocol.CanalEntry.*;
import 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值