Canal 详解

本文探讨了阿里巴巴开源的Canal,如何通过MySQLbinlog实现实时数据同步,以及其在缓存、任务调度和数据异构中的应用,配合RabbitMQ实现高效数据流转。
摘要由CSDN通过智能技术生成

Canal是阿里开源的一款基于Mysql数据库binlog的增量订阅和消费组件,通过它可以订阅数据库的binlog日志,然后进行一些数据消费,如数据镜像、数据异构、数据索引、缓存更新等。相对于消息队列,通过这种机制可以实现数据的有序化和一致性。

  1. canal模拟mysql slave与mysql master的交互协议,伪装自己是一个mysql slave,向mysql master发送dump协议;
  2. mysql master收到mysql slave(canal)发送的dump请求,开始推送binlog增量日志给slave(也就是canal);
  3. mysql slave(canal伪装的)收到binlog增量日志后,就可以对这部分日志进行解析,获取主库的结构及数据变更;

canal工作原理其实也是基于mysql主从同步原理的,所以理解mysql主从同步原理是第一步

  同步原理:

  1. Master主库,启动Binlog机制,将变更数据写入Binlog文件;
  2. Slave(I/O thread),从Master主库拉取binlon数据,将它拷贝到Slave的中继日志(relay log)中;
  3. Slave(SQL thread),回放Binlog,更新从库数据;

   启用Binlog注意以下几点:

  1. Master主库一般会有多台Slave订阅,且Master主库要支持业务系统实时变更操作,服务器资源会有瓶颈;
  2.  需要同步的数据表一定要有主键;

Canal

说明:
server代表一个canal运行实例,对应于一个jvm
instance对应于一个数据队列

instance模块:
eventParser (数据源接入,模拟slave协议和master进行交互,协议解析)
eventSink (Parser和Store链接器,进行数据过滤,加工,分发的工作)
eventStore (数据存储)
metaManager (增量订阅&消费信息管理器)


应用场景

1、同步缓存redis/全文搜索ES

canal一个常见应用场景是同步缓存/全文搜索,当数据库变更后通过binlog进行缓存/ES的增量更新。当缓存/ES更新出现问题时,应该回退binlog到过去某个位置进行重新同步,并提供全量刷新缓存/ES的方法,如下图所示。

2、下发任务

另一种常见应用场景是下发任务,当数据变更时需要通知其他依赖系统。其原理是任务系统监听数据库变更,然后将变更的数据写入MQ/kafka进行任务下发,比如商品数据变更后需要通知商品详情页、列表页、搜索页等先关系统。这种方式可以保证数据下发的精确性,通过MQ发送消息通知变更缓存是无法做到这一点的,而且业务系统中不会散落着各种下发MQ的代码,从而实现了下发归集,如下图所示。

3、数据异构

在大型网站架构中,DB都会采用分库分表来解决容量和性能问题,但分库分表之后带来的新问题。比如不同维度的查询或者聚合查询,此时就会非常棘手。一般我们会通过数据异构机制来解决此问题。

所谓的数据异构,那就是将需要join查询的多表按照某一个维度又聚合在一个DB中。让你去查询。canal就是实现数据异构的手段之一。


SpringBoot 整合 Canal + RabbitMQ

MySQL

开启 biglog 日志

vim /etc/my.cnf

添加配置

[mysqld]
log-bin=mysql-bin # 开启binlog
binlog-format=ROW # 选择ROW模式
server_id=1 # 配置MySQL replaction需要定义,不和Canal的slaveId重复即可

重启MySQL ,查看配置是否生效

show variables like 'log_bin';

在这里插入图片描述

RabbitMQ
  • 添加交换机 canal.exchange

youlai-mall

  • 添加队列 canal.queue
    在这里插入图片描述

  • 队列绑定交换机

在这里插入图片描述
在这里插入图片描述

Canal
下载

进入下载地址,选择 canal.deployer-1.1.5.tar.gz

youlai-mall

将压缩包解压,我这里把最后解压出来的文件放入 有来项目 的middleware中间件文件,和之前的 nacos 和 sentinel 同一个套路。

在这里插入图片描述

Canal Server配置

需要配置的东西就两项,一个是监听数据库配置,另一个是 RabbitMQ 连接配置。

改动的两个文件分别是 Canal 配置文件 canal.properties 和 实例配置文件 instance.properties

㊙️:一个 Server 可以配置多个实例监听 ,Canal 功能默认自带的有个 example 实例,本篇就用 example 实例 。如果增加实例,复制 example 文件夹内容到同级目录下,然后在 canal.properties 指定添加实例的名称。

在这里插入图片描述

  • canal.properties

    配置 Canal 服务方式为 RabbitMQ 和连接配置(🏷️ 只列出需要修改的地方)

    # tcp, kafka, rocketMQ, rabbitMQ
    canal.serverMode = rabbitMQ
    ##################################################
    ######### 		    RabbitMQ	     #############
    ##################################################
    rabbitmq.host = x.youlai.tech
    rabbitmq.virtual.host =/
    rabbitmq.exchange =canal.exchange
    rabbitmq.username =guest
    rabbitmq.password =guest
    rabbitmq.deliveryMode =
    
  • instance.properties

    监听数据库配置(🏷️ 只列出需要修改的地方)

    # position info
    canal.instance.master.address=x.youlai.tech:3306
    # username/password
    canal.instance.dbUsername=root
    canal.instance.dbPassword=root
    # mq config
    canal.mq.topic=canal.routing.key

SpringBoot
引入依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
RabbitMQ连接配置
spring:
  rabbitmq:
    host: x.youlai.tech
    port: 5672
    username: guest
    password: guest
RabbitMQ 监听同步缓存
/**
 * Canal + RabbitMQ 监听数据库数据变化
 *
 * @author <a href="mailto:xianrui0365@163.com">haoxr</a>
 * @date 2021/11/4 23:14
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class CanalListener {

    private final ISysPermissionService permissionService;
    private final ISysOauthClientService oauthClientService;
    private final ISysMenuService menuService;

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = "canal.queue", durable = "true"),
                    exchange = @Exchange(value = "canal.exchange"),
                    key = "canal.routing.key"
            )
    })
    public void handleDataChange(@Payload CanalMessage message) {
        String tableName = message.getTable();

        log.info("Canal 监听 {} 发生变化;明细:{}", tableName, message);

        if ("sys_oauth_client".equals(tableName)) {
            log.info("======== 清除客户端信息缓存 ========");
            oauthClientService.cleanCache();
        } else if (Arrays.asList("sys_permission", "sys_role", "sys_role_permission").contains(tableName)) {
            log.info("======== 刷新角色权限缓存 ========");
            permissionService.refreshPermRolesRules();
        } else if (Arrays.asList("sys_menu", "sys_role", "sys_role_menu").contains(tableName)) {
            log.info("======== 清理菜单路由缓存 ========");
            menuService.cleanCache();
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值