canal实践

一、what

阿里开源,mysql增量数据订阅与消费服务,文档:https://github.com/alibaba/canal/wiki

工作原理:canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送 dump 协议
MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
canal 解析 binary log 对象(原始为 byte 流)

二、why

工作中遇到一个查询场景,需要多张表的数据(8张)做聚合,且某些表数据量较大,还需要反复join,导致sql极复杂&查询速度极慢,于是打算将这些数据聚合成一张宽表,每次查询直接从宽表中查询。

三、how

1. 整体架构:canal-server监听mysql的binlog ------→ canal-client接收来自canal-server发出的数据变更消息&计算宽表数据 -------→ 写入宽表。canal-client是自己搭建的java服务,实现宽表聚合的具体计算逻辑。canal-server实际是帮我们做了binlog的解析,将解析后的数据发送给canal-client

2. 步骤

    1. 运维同学搭建canal-server,监听对应mysql的binlog服务并做相关配置

    2. 开发同学搭建canal-client,连上canal-server,消费数据变更,开发程序,根据业务场景集合宽表

四、其他

1. 问题:mysql数据变更后,canal-client未收到数据变更消息

    原因:binlog过期自动被清除,canal server还未来得及解析,导致canal server每次启动时都从binlog的144文件开始读,但是现在最早的位置在146文件,146之前的binlog都已被删除,canal-server读取binlog失败。
    具体情况说明:(基于”canal-client消费后才会驱动canal-server解析binlog的游标移动,否则canal-server的游标停留在原位置"的原理)。DBA设置的binlog为7天有效期,过期删除,运维同学搭建好canal-server后,我这边因为有其他事,一直未开始投入client的开发,所以一直未启动canal-client消费,那天启动canal-client消费过程中,一开始是正常的,后边突然收不到数据变更消息,其实是某些binlog刚好到期时间被删除,导致canal-server读取binlog失败。

    解决方案:重新初始化server读取binlog的游标,并且延长binlog的过期时间。

2. 问题:收到的数据与配置的监听表不一致,eg. 配置的监听表A,但是收到了表B的变更消息
    原因:canal-client未进行监听表过滤。不写connector.subscribe()或者写成connector.subscribe()都会把服务端的规则覆盖掉,需要显示指定监听规则。(无论 server filter 配置成什么,都会被 client 的 subscribe 参数替换掉,奇葩

3. Q:可以多个client连接同一个server下的instance吗?
    A:可以,数据分发方式是:串联&轮训的方式给每个client提供数据,也就是消息发给clientA就不会再发给其他的client了,非广播发送。(待验证)

4. 消息、乱序重复:做幂等处理
         增加:按照业务主键做幂等,若已记录已存在,则忽略消息

         修改:按照业务主键+更新时间做幂等,若数据变更事件发生的时间 < 宽表数据的更新时间,说明是过期消息,需要忽略消息,否则可能出现ABA问题

         删除:无影响

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值