Canal初识

本文介绍了如何利用Cannal监听MySQL的binlog,实现操作日志的记录。通过开启binlog并设置ROW模式,Cannal伪装成slave与MySQL交互,解析binlog获取数据变化。在面临数据库查询耗内存和不支持多表操作的问题时,Cannal提供了一种高效解决方案。启动Cannal实例,配置连接信息,启动客户端并观察更新操作的实时反馈。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

  1. 项目需要记录操作日志,记录数据前后的变化
  2. 网上搜索diff开源实现有很多,但怎么获取操作前后的对象?
    2.1 最直观的方式,就是在操作前后查询数据库,但这样会有几个问题
    (1)譬如update操作,where条件带出来数据很多,这样对比很耗内存
    (2)不支持多表操作
    2.2 参考的实现方案有:
    (1)知乎文章:https://www.zhihu.com/question/26848331
    (2)基于主键ID的实现:https://blog.youkuaiyun.com/Howinfun/article/details/114368019
    (3)AOP和binlog的对比:https://cloud.tencent.com/developer/article/1625912
  3. AOP的实现方案不满足业务需求,尝试根据binlog去实现,而cannal就是监听binlog的,所以有了下面的初识

Cannal介绍

cannal的工作原理

在这里插入图片描述

  1. cannal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议
  2. mysql matser收到dump请求,开始推送binary log给slave(也就是cannal)
  3. cannal解析binary log对象(原始为byte流)

架构

在这里插入图片描述

  1. 说明
    1.1 server代表一个cannal运行实例,对应于一个jvm
    1.2 instance对应于一个数据队列(1个server对应1…n个instance)
  2. instance模块:
    2.1 eventParser (数据源接入,模拟slave协议和master进行交互,协议解析)
    2.2 eventSink (Parser和Store链接器,进行数据过滤,加工,分发的工作)
    2.3 eventStore (数据存储)
    2.4 metaManager (增量订阅&消费信息管理器)

知识科普

  1. mysql的binlog是多文件存储,定位一个LogEvent需要通过binlog filename + binlog position,进行定位
  2. mysql的binlog数据格式,按照生成的方式,主要分为:statement-based、row-based、mixed
    	mysql> show variables like 'binlog_format';
    	+---------------+-------+
    	| Variable_name | Value |
    	+---------------+-------+
    	| binlog_format | ROW   |
    	+---------------+-------+
    	1 row in set (0.00 sec)
    
  3. 目前canal支持所有模式的增量订阅(但配合同步时,因为statement只有sql,没有数据,无法获取原始的变更日志,所以一般建议为ROW模式)

简单应用

MYSQL配置准备

  1. 对于自建 MySQL,需要先开启 Binlog 写入功能,配置 binlog-format 为 ROW 模式,my.cnf 中配置如下

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

    1.1 注意:针对阿里云 RDS for MySQL , 默认打开了 binlog , 并且账号默认具有 binlog dump 权限 , 不需要任何权限或者 binlog 设置,可以直接跳过这一步

  2. 授权 canal 链接 MySQL 账号具有作为 MySQL slave 的权限, 如果已有账户可直接 grant

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

补充

  1. 查看本地mysql的安装路径:show variables like “%char%”
    在这里插入图片描述
  2. 查看mysql数据库是否开启binlog: show variables like ‘log_bin’;
    在这里插入图片描述
  3. windows查看my.ini的位置:https://blog.youkuaiyun.com/qq_27680317/article/details/71107934
    	--defaults-file="C:\ProgramData\MySQL\MySQL Server 5.7\my.ini"
    
  4. windows修改my.ini配置重启mysql生效
    在这里插入图片描述
    在这里插入图片描述
  5. 查看用户的权限:show grants for ‘canal’
    在这里插入图片描述

启动Cannal

  1. 下载canal的deployer包(我下的是v1.1.5)
  2. 配置修改(conf/example/instance.properties)
    ## mysql serverId
    canal.instance.mysql.slaveId = 1234
    #position info,需要改成自己的数据库信息
    canal.instance.master.address = 127.0.0.1:3306 
    canal.instance.master.journal.name = 
    canal.instance.master.position = 
    canal.instance.master.timestamp = 
    #canal.instance.standby.address = 
    #canal.instance.standby.journal.name =
    #canal.instance.standby.position = 
    #canal.instance.standby.timestamp = 
    #username/password,需要改成自己的数据库信息
    canal.instance.dbUsername = canal  
    canal.instance.dbPassword = canal
    canal.instance.defaultDatabaseName =
    canal.instance.connectionCharset = UTF-8
    #table regex
    canal.instance.filter.regex = .\*\\\\..\*
    
  3. 启动(进入bin/startup.bat)
    3.1 启动控制台发现,启动类为CanalLauncher
    在这里插入图片描述
    3.2 在IDEA上添加远程调式的端口即可远程调式
    在这里插入图片描述
  4. 查看日志
    4.1 查看server日志(logs/canal/canal.log)
    在这里插入图片描述
    4.2 查看 instance 的日志(logs/example/example.log)
    2021-10-13 11:05:51.487 [main] INFO  c.a.otter.canal.instance.spring.CanalInstanceWithSpring - start CannalInstance for 1-example 
    2021-10-13 11:05:51.499 [main] WARN  c.a.o.canal.parse.inbound.mysql.dbsync.LogEventConvert - --> init table filter : ^.*\..*$
    2021-10-13 11:05:51.499 [main] WARN  c.a.o.canal.parse.inbound.mysql.dbsync.LogEventConvert - --> init table black filter : ^mysql\.slave_.*$
    2021-10-13 11:05:51.504 [main] INFO  c.a.otter.canal.instance.core.AbstractCanalInstance - start successful....
    2021-10-13 11:05:51.561 [destination = example , address = /127.0.0.1:3306 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> begin to find start position, it will be long time for reset or first position
    2021-10-13 11:05:51.562 [destination = example , address = /127.0.0.1:3306 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - prepare to find start position just show master status
    2021-10-13 11:05:53.408 [destination = example , address = /127.0.0.1:3306 , EventParser] WARN  c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - ---> find start position successfully, EntryPosition[included=false,journalName=mysql-bin.000001,position=4,serverId=1,gtid=<null>,timestamp=1634092895000] cost : 1841ms , the next step is binlog dump
    

演示

  1. 启动客户端demo(下载cannal源码,在example模块的SimpleCanalClientTest#main)
  2. 在Mysql客户端执行update语句,观察客户端的控制台输出
    在这里插入图片描述

总结

  1. 上面简单介绍了Cannal的工作原理和代码架构,并且按照官网指引进行了启动,后续以CanalLauncher入口进行源码调式
  2. 在启动cannal之后,然后启动客户端SimpleCanalClientTest,最后在Mysql客户端执行update语句观察控制台输出
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值