Canal的使用

Canal的使用

Canal概述

canal是用java开发的基于数据库增量日志解析,提供增量数据订阅&消费的中间件。目前,canal主要支持了MySQL的binlog解析,解析完成后才利用canal client 用来处理获得的相关数据。(数据库同步需要阿里的otter中间件,基于canal)。

使用场景

  • 原始场景:作为异地数据库之间的数据同步

  • 更新缓存

  • 抓取业务新增变化表,用于制作拉链表

  • 实时抓取业务数据中的新增变化数据,用于制作实时统计

    Canal原理

    Mysql的主从复制原理:

    1. Master主库将改变记录,写到二进制日志(binary log)中

    2. Slave从库向mysql master发送dump协议,将master主库的binary log events拷贝到它的中继日志(relay log);

    3. Slave从库读取并重做中继日志中的事件,将改变的数据同步到自己的数据库。

    Canal原理:

    img

1.canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议

2.mysql master收到dump请求,开始推送binary log给slave(也就是canal)

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

Mysql的BinLog

  • 什么是Binlog日志?

MySQL的二进制日志可以说是MySQL最重要的日志了,它记录了所有的DDL和DML(除了数据查询语句)语句,以事件形式记录,还包含语句所执行的消耗的时间,MySQL的二进制日志是事务安全型的。

一般来说开启二进制日志大概会有1%的性能损耗 。二进制有两个最重要的使用场景: 

其一:MySQL Replication在Master端开启binlog,Mster把它的二进制日志传递给slaves来达到master-slave数据一致的目的。 

其二:自然就是数据恢复了,通过使用mysqlbinlog工具来使恢复数据。

二进制日志包括两类文件:二进制日志索引文件(文件名后缀为.index)用于记录所有的二进制文件,二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML(除了数据查询语句)语句事件。

  • binLog日志的开启

    • 1.修改mysql的配置文件 /etc/my.conf

      添加如下

    log-bin=mysql-bin  // 这个表示binlog日志的前缀是mysql-bin  ,以后生成的日志文件就是 mysql-bin.123456 的文件后面的数字按顺序生成。 每次mysql重启或者到达单个文件大小的阈值时,新生一个文件,按顺序编号。
    
    • 2.mysql binlog的格式,那就是有三种,分别是STATEMENT,MIXED,ROW。在配置文件中可以选择配置
binlog_format=row

​ STATEMENT,MIXED,ROW的区别:

  1. statement :语句级,binlog会记录每次一执行写操作的语句。 相对row模式节省空间,但是可能产生不一致性,比如update tt set create_date=now() 如果用binlog日志进行恢复,由于执行时间不同可能产生的数据就不同。

​ 优点: 节省空间

​ 缺点: 有可能造成数据不一致。

  1. row 行级, binlog会记录每次操作后每行记录的变化。

​ 优点:保持数据的绝对一致性。因为不管sql是什么,引用了什么函数,他只记录执行后的效果。

​ 缺点:占用较大空间。

  1. mixed statement的升级版,一定程度上解决了,因为一些情况而造成的statement模式不一致问题 ,在某些情况下譬如:

​ 当函数中包含 UUID() 时;

	包含 AUTO_INCREMENT 字段的表被更新时;

​ 执行 INSERT DELAYED 语句时;

​ 用 UDF 时;

​ 会按照 ROW的方式进行处理

​ 优点:节省空间,同时兼顾了一定的一致性。

​ 缺点:还有些极个别情况依旧会造成不一致,另外statement和mixed对于需要对binlog的监控的情况都不方便。

  1. 在mysql中赋予权限:
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%' IDENTIFIED BY 'canal' ;
  1. 修改 /etc/my.conf 文件
server-id= 1
log-bin=mysql-bin
binlog_format=row
binlog-do-db=xxx  //指得你要监控的数据库

  1. 重启mysql

Canal的安装

  1. 去https://github.com/alibaba/canal/releases 下载安装版本

  2. 把canal.deployer-1.1.2.tar.gz拷贝到linux,解压缩

  3. 修改 canal配置及

    vim conf/canal.properties, 此配置为Canal的默认配置,主要关注端口号

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VLg0nvLe-1589105749433)(C:\Users\txc\AppData\Roaming\Typora\typora-user-images\image-20200510180920445.png)]
    配置canal监控的实例,destination可以配置多个,在客户端的代码中destination要对应

在这里插入图片描述
10. vim conf/example/instance.properties。instance.properties是针对要追踪的mysql的实例配置

11.启动canal,./bin/startup.sh

  1. 启动客户端抓取数据
  2. canal的数据结构
Entry
    Header
        version         [协议的版本号,default = 1]
        logfileName     [binlog文件名]
        logfileOffset   [binlog position]
        serverId        [服务端serverId]
        serverenCode    [变更数据的编码]
        executeTime     [变更数据的执行时间]
        sourceType      [变更数据的来源,default = MYSQL]
        schemaName      [变更数据的schemaname]
        tableName       [变更数据的tablename]
        eventLength     [每个event的长度]
        eventType       [insert/update/delete类型,default = UPDATE]
        props           [预留扩展]
        gtid            [当前事务的gitd]
    entryType           [事务头BEGIN/事务尾END/数据ROWDATA/HEARTBEAT/GTIDLOG]
    storeValue          [byte数据,可展开,对应的类型为RowChange]    
RowChange
    tableId             [tableId,由数据库产生]
    eventType           [数据变更类型,default = UPDATE]
    isDdl               [标识是否是ddl语句,比如create table/drop table]
    sql                 [ddl/query的sql语句]
    rowDatas            [具体insert/update/delete的变更数据,可为多条,1个binlog event事件可对应多条变更,比如批处理]
        beforeColumns   [字段信息,增量数据(修改前,删除前),Column类型的数组]
        afterColumns    [字段信息,增量数据(修改后,新增后),Column类型的数组] 
        props           [预留扩展]
    props               [预留扩展]
    ddlSchemaName       [ddl/query的schemaName,会存在跨库ddl,需要保留执行ddl的当前schemaName]
Column 
    index               [字段下标]      
    sqlType             [jdbc type]
    name                [字段名称(忽略大小写),在mysql中是没有的]
    isKey               [是否为主键]
    updated             [是否发生过变更]
    isNull              [值是否为null]
    props               [预留扩展]
    value               [字段值,timestamp,Datetime是一个时间格式的文本]
    length              [对应数据对象原始长度]
    mysqlType           [字段mysql类型]

Canal是阿里巴巴开源的数据库增量日志解析,提供增量数据订阅&消费,在使用过程中可能会遇到以下常见问题及对应的解决方案: ### 无法连接到Canal Server Canal Client 无法连接到Canal Server,可能是由于网络问题、Canal Server未启动或者配置错误导致。 - **网络问题**:检查客户端和服务端之间的网络连接是否正常,可以使用`ping`和`telnet`命令来验证。例如,使用`telnet <canal-server-ip> <canal-server-port>`测试端口连通性。 - **Canal Server未启动**:检查Canal Server的启动状态,可查看启动日志文件(通常在`canal-server/logs/canal/canal.log`)来确认是否有启动异常信息。若未启动,使用`sh bin/startup.sh`命令启动。 - **配置错误**:检查Canal Client的配置文件,确保`canal.server.host`和`canal.server.port`配置正确。 ### 数据同步延迟 在使用Canal进行数据同步时,可能会出现数据同步延迟的问题,这可能是由于数据库压力大、Canal Server处理能力不足或者网络延迟导致。 - **数据库压力大**:优化数据库的性能,如增加数据库服务器的硬件资源、优化数据库的查询语句、创建合适的索引等。 - **Canal Server处理能力不足**:可以考虑增加Canal Server的实例数量,进行负载均衡,或者优化Canal Server的配置参数,如调整`canal.instance.parser.parallel`参数提高解析并行度。 - **网络延迟**:检查网络环境,尽量减少网络延迟,如将Canal Server和数据库部署在同一局域网内。 ### 数据解析异常 Canal在解析数据库日志时可能会出现异常,导致数据解析错误,这可能是由于数据库版本不兼容、日志格式不支持或者Canal配置错误导致。 - **数据库版本不兼容**:确保Canal支持当前使用的数据库版本,如Canal对MySQL不同版本的支持情况有所差异,参考Canal官方文档确认兼容性。 - **日志格式不支持**:检查数据库的日志格式配置,确保使用的是Canal支持的日志格式,如MySQL需要将`binlog_format`设置为`ROW`。 - **Canal配置错误**:检查Canal Server的配置文件,确保`canal.instance.master.journal.name`、`canal.instance.master.position`等配置正确。 ### 重复消费数据 Canal Client在消费数据时可能会出现重复消费的情况,这可能是由于消费位点记录异常或者客户端异常重启导致。 - **消费位点记录异常**:检查Canal Client的消费位点记录机制,确保消费位点能够正确记录和恢复。可以使用Canal提供的`MetaManager`接口来管理消费位点。 - **客户端异常重启**:在客户端重启时,确保能够正确恢复到上次消费的位点。可以在客户端代码中添加异常处理逻辑,在异常发生时记录当前消费位点,重启后从该位点继续消费。 ```java // 示例代码:使用Canal Client消费数据 import com.alibaba.otter.canal.client.CanalConnector; import com.alibaba.otter.canal.client.CanalConnectors; import com.alibaba.otter.canal.protocol.CanalEntry; import com.alibaba.otter.canal.protocol.Message; import java.net.InetSocketAddress; import java.util.List; public class CanalClientExample { public static void main(String[] args) { // 创建Canal连接 CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("127.0.0.1", 11111), "example", "", ""); try { // 连接到Canal Server connector.connect(); // 订阅数据库表 connector.subscribe(".*\\..*"); while (true) { // 获取数据 Message message = connector.get(100); List<CanalEntry.Entry> entries = message.getEntries(); if (entries != null && !entries.isEmpty()) { for (CanalEntry.Entry entry : entries) { if (entry.getEntryType() == CanalEntry.EntryType.ROWDATA) { // 处理数据 processEntry(entry); } } } } } finally { // 关闭连接 connector.disconnect(); } } private static void processEntry(CanalEntry.Entry entry) { // 处理数据的具体逻辑 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值