canal简单介绍

简介

https://github.com/alibaba/canal

基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费

原理是使用程序模拟一个mysql的从库,使主库发送同步日志给程序,程序再对数据进行处理,比如同步到其他数据库。

使用

下图是一个典型的将mysql增量数据同步到es的流程

这里要注意的是,canal client不是连接数据库,而是必须连接到canal server上的

canal server: canal 服务端,内部可包含多个canal instance

canal instance: 运行在canal server中, 可被canal client连接

canal client: 集成在业务代码中,可连接canal instacne读取bin-log事件,并进行相应处理

安装canal 服务端

直接使用docker来安装
https://github.com/alibaba/canal/wiki/Docker-QuickStart

下载官方镜像及run.sh文档

shell 复制代码
docker pull canal/canal-server:latest
wget https://raw.githubusercontent.com/alibaba/canal/master/docker/run.sh

可以根据需要修改一下run.sh时面的一些端口和内存配置,然后编写自己的start.sh脚本

shell 复制代码
#!/bin/sh
run.sh -e canal.auto.scan=false \
      -e canal.instance.mysql.slaveId=10001 \
      -e canal.zkServers=192.168.1.10:1100 \
        -e canal.instance.global.spring.xml=classpath:spring/default-instance.xml \
                  -e canal.destinations=test \
                  -e canal.instance.master.address=127.0.0.1:3306  \
                  -e canal.instance.dbUsername=canal  \
                  -e canal.instance.dbPassword=canal  \
                  -e canal.instance.connectionCharset=UTF-8 \
                  -e canal.instance.tsdb.enable=true \
                  -e canal.instance.gtidon=false  \
                  -e canal.instance.filter.regex=.*\\..*

canal服务端配置说明:
https://github.com/alibaba/canal/wiki/AdminGuide

canal.destinations:实例列表

canal.instance.master.address: 源数据库地址

canal.instance.dbUsername:源数据库用户名

canal.instance.dbPassword: 源数据库密码

canal.instance.connectionCharset: 数据库连接字符集

canal.instance.filter.regex:需要处理的表(Perl正则表达式),多个规则使用','分隔

线上是使用阿云数据库,阿里云binlog是默认开启的,本地保留时间为18小时,一般来说够用了,不够的话就要去配置保存到oss了。https://github.com/alibaba/canal/wiki/aliyun-RDS-QuickStart

集成客户端

导入库

shell 复制代码
    compile('com.alibaba.otter:canal.client:1.1.6') {
        exclude group: 'org.slf4j'
        exclude group: 'ch.qos.logback'
    }
    compile('com.alibaba.otter:canal.protocol:1.1.6') {
        exclude group: 'org.slf4j'
        exclude group: 'ch.qos.logback'
    }

代码示例

java 复制代码
//创建连接
CanalConnector connector = CanalConnectors.newClusterConnector("192.168.1.10:1100", "test", "", "");
//连接服务端
connector.connect();
connector.subscribe();
//循环获取事件
while (running) {
    Message message = connector.getWithoutAck(batchSize); // 获取指定数量的数据
    long batchId = message.getId();
    int size = message.getEntries().size();
    if (batchId == -1 || size == 0) {
	//无数据时睡眠一会
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
        }
    } else {
	//开始处理数据
        for (CanalEntry.Entry entry : message.getEntries()) {
            switch (entry.getEntryType()) {
                case TRANSACTIONBEGIN:
                    processTransactionBegin(entry);
                    break;
                case ROWDATA:
                    processRawDataEntry(entry);
                    break;
                case TRANSACTIONEND:
                    processTransactionEnd(entry);
                    break;
            }
        }
    }

    if (batchId != -1) {
        connector.ack(batchId); // 提交确认
    }
}

值得注意的是,canal事件包含事务开始,数据,事务结束等,一般来说一个事务会在一个message中返回,但也有可能在多个message中,这个和batchSize、服务端缓冲区大小有关系。

一个message中只会包含一个事务。

在没有提交事务之前,binlog不会同步给从服务器,所以canal收到的事件都是提交之后的。

相关推荐
Ren_xixi1 小时前
redis和mysql的区别
数据库·redis·mysql
追逐时光者3 小时前
免费、简单、直观的数据库设计工具和 SQL 生成器
后端·mysql
drebander3 小时前
MySQL 查询优化案例分享
数据库·mysql
初晴~3 小时前
【Redis分布式锁】高并发场景下秒杀业务的实现思路(集群模式)
java·数据库·redis·分布式·后端·spring·
雷神乐乐5 小时前
Spring学习(一)——Sping-XML
java·学习·spring
小林coding6 小时前
阿里云 Java 后端一面,什么难度?
java·后端·mysql·spring·阿里云
文大。6 小时前
2024年广西职工职业技能大赛-Spring
java·spring·网络安全
18号房客6 小时前
高级sql技巧进阶教程
大数据·数据库·数据仓库·sql·mysql·时序数据库·数据库架构
小马爱打代码7 小时前
Spring Boot 中 Map 的最佳实践
java·spring boot·spring
翔云1234567 小时前
MySQL purged gtid是如何生成和维护的
数据库·mysql