基于canal实现mysql和es增量数据同步

一、简介

canal主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费。

二、工作原理

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

MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )

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

三、基于canal实现mysql和es增量数据同步

3.1 基于canalServer和canalAdapter的方式进行数据同步

worker:数据全量同步组件

canalServer:接收binlog信息

canalAdapter:canalServer和elasticSearch适配

canal作为增量数据同步的工具,同时对不同数据源做了适配,canalAdapter目前默认支持的数据源有:Hbase,ElasticSearch和RDB(关系型数据库)。

通过canalServer和canalAdapter的一些配置(各个中间件配置信息请参考官方文档),无需代码开发就能实现不同数据源之间的同步。

但是用这种方式如果数据量大,可能会产生数据积压,有数据丢失的风险。

3.2基于mq和canalClient的方式进行数据同步

canal 1.1.1版本之后, 默认支持将canalServer接收到的binlog数据直接投递到MQ, 目前默认支持的MQ系统有:kafka和RocketMQ。

我们需要在应用中开发canalClient,esClient和mqConsumer组件

canalClient:将消息解析并封装成对应实体

esClient:elasticSearch基本操作

mqConsumer:消费消息,通过canalClient将消息解析成对应的实体对象,通过esClient将对象写入到elasticSearch集群。

canalClient的关键代码解析Message中的Entries,代码如下:

private static void printEntry(List<Entry> entrys) {
        for (Entry entry : entrys) {
            if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) {
                continue;
            }
            RowChange rowChage;
            try {
                rowChage = RowChange.parseFrom(entry.getStoreValue());
            } catch (Exception e) {
                throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(), e);
            }
            //获取操作类型:insert/update/delete类型
            EventType eventType = rowChage.getEventType();
            //打印Header信息
            System.out.println(String.format("================》; binlog[%s:%s] , name[%s,%s] , eventType : %s",
                    entry.getHeader().getLogfileName(), entry.getHeader().getLogfileOffset(),
                    entry.getHeader().getSchemaName(), entry.getHeader().getTableName(),
                    eventType));
            //判断是否是DDL语句
            if (rowChage.getIsDdl()) {
                System.out.println("================》;isDdl: true,sql:" + rowChage.getSql());
            }
            //获取RowChange对象里的每一行数据,打印出来
            for (RowData rowData : rowChage.getRowDatasList()) {
                //如果是删除语句
                if (eventType == EventType.DELETE) {
                    printColumn(rowData.getBeforeColumnsList());
                    //如果是新增语句
                } else if (eventType == EventType.INSERT) {
                    printColumn(rowData.getAfterColumnsList());
                    //如果是更新的语句
                } else {
                    //变更前的数据
                    printColumn(rowData.getBeforeColumnsList());
                    //变更后的数据
                    printColumn(rowData.getAfterColumnsList());
                }
            }
        }
    }

四、小结

canal只适合做增量数据同步,全量数据同步需要采用其他的方式来实现。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值