1.概要

canal 是阿里发布的一个mysql 同步工具,它是模拟 mysql slave 的方式读取binlog,并可以将数据写入到队列中。

如下图:是官方提供的架构图。

2.下载CANAL

下载版本为1.1.5

其中

canal.deployer 是canal服务器

canal.admin 是CANAL可视化管理界面

3.配置canal

3.1 配置mysql

创建用户并授权

 create user 'canal'@'%' identified by 'canal';
grant SELECT, REPLICATION SLAVE, REPLICATION CLIENT on *.* to 'canal'@'%';

配置mysql

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

配置后重启mysql

查看binlog文件列表

查看当前写入的log文件

3.2 配置canal

编辑文件 conf/example/instance.properties

canal.instance.gtidon=false

# mysql地址
canal.instance.master.address=localhost:3306
# mysql 日志文件
canal.instance.master.journal.name=mysql-bin.000001
# 配置日志起始位置,配置为上图的 position。
canal.instance.master.position=3970
canal.instance.master.timestamp=
canal.instance.master.gtid= # rds oss binlog
canal.instance.rds.accesskey=
canal.instance.rds.secretkey=
canal.instance.rds.instanceId= # table meta tsdb info
canal.instance.tsdb.enable=true # 用户名密码
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
canal.instance.connectionCharset = UTF-8
# enable druid Decrypt database password
canal.instance.enableDruid=false
#canal.instance.pwdPublicKey=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALK4BUxdDltRRE5/zXpVEVPUgunvscYFtEip3pmLlhrWpacX7y7GCMo2/JM6LeHmiiNdH1FWgGCpUfircSwlWKUCAwEAAQ== # table regex
canal.instance.filter.regex=.*\\..*
# table black regex
canal.instance.filter.black.regex=mysql\\.slave_.* # mq config
canal.mq.topic=example
# dynamic topic route by schema or table regex
#canal.mq.dynamicTopic=mytest1.user,mytest2\\..*,.*\\..*
canal.mq.partition=0

配置好后

正常的启动如下

是否启动成功,我们可以查看日志数据。

如果是mysql8 可能会报如下错误

Canal 1.1.5 启动报错:caching_sha2_password Auth failed

这个是mysql 的密码验证失败。

ALTER USER 'canal'@'%' IDENTIFIED WITH mysql_native_password BY 'canal';

执行这个后,在启动canal。

3.3 开发java程序读取同步数据

开发一个springboot程序。

引入jar包。

<dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.client</artifactId>
<version>1.1.5</version>
</dependency> <dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.protocol</artifactId>
<version>1.1.5</version>
</dependency>

开发编辑代码如下:

package com.example.canaldemo;

import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.protocol.CanalEntry;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import com.alibaba.otter.canal.protocol.Message;
import com.alibaba.otter.canal.protocol.exception.CanalClientException; import java.net.InetSocketAddress;
import java.util.List; @Component
public class CannalClient implements InitializingBean { private final static int BATCH_SIZE = 1000; @Override
public void afterPropertiesSet() throws Exception {
// 创建链接
CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("127.0.0.1", 11111),
"example", "", "");
try {
//打开连接
connector.connect();
//订阅数据库表,全部表
connector.subscribe(".*\\..*");
//回滚到未进行ack的地方,下次fetch的时候,可以从最后一个没有ack的地方开始拿
connector.rollback();
while (true) {
// 获取指定数量的数据
Message message = connector.getWithoutAck(BATCH_SIZE);
//获取批量ID
long batchId = message.getId();
//获取批量的数量
int size = message.getEntries().size();
//如果没有数据
if (batchId == -1 || size == 0) {
try {
//线程休眠2秒
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
//如果有数据,处理数据
printEntry(message.getEntries());
}
//进行 batch id 的确认。确认之后,小于等于此 batchId 的 Message 都会被确认。
connector.ack(batchId);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
connector.disconnect();
}
} /**
* 打印canal server解析binlog获得的实体类信息
*/
private static void printEntry(List<CanalEntry.Entry> entrys) {
for (CanalEntry.Entry entry : entrys) {
if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN || entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONEND) {
//开启/关闭事务的实体类型,跳过
continue;
}
//RowChange对象,包含了一行数据变化的所有特征
//比如isDdl 是否是ddl变更操作 sql 具体的ddl sql beforeColumns afterColumns 变更前后的数据字段等等
CanalEntry.RowChange rowChage;
try {
rowChage = CanalEntry.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类型
CanalEntry.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 (CanalEntry.RowData rowData : rowChage.getRowDatasList()) {
//如果是删除语句
if (eventType == CanalEntry.EventType.DELETE) {
printColumn(rowData.getBeforeColumnsList());
//如果是新增语句
} else if (eventType == CanalEntry.EventType.INSERT) {
printColumn(rowData.getAfterColumnsList());
//如果是更新的语句
} else {
//变更前的数据
System.out.println("------->; before");
printColumn(rowData.getBeforeColumnsList());
//变更后的数据
System.out.println("------->; after");
printColumn(rowData.getAfterColumnsList());
}
}
}
} private static void printColumn(List<CanalEntry.Column> columns) {
for (CanalEntry.Column column : columns) {
System.out.println(column.getName() + " : " + column.getValue() + " update=" + column.getUpdated());
}
}
}

执行后,我们操作数据库表,比如删除数据。

这样我们就可以通过java程序读取canal读取的数据。当然我们可以通过代码将数据插入到其他的数据库中。

使用CANAL同步数据的更多相关文章

  1. 用canal监控binlog并实现mysql定制同步数据的功能

    业务背景 写任何工具都不能脱离实际业务的背景.开始这个项目的时候是因为现有的项目中数据分布太零碎,零零散散的分布在好几个数据库中,没有统一的数据库来收集这些数据.这种情况下想做一个大而全的会员中心系统 ...

  2. canal同步MySQL数据到ES6.X

    背景: 最近一段时间公司做一个技术架构的更改,由于之前使用的solr和目前的业务不太匹配,具体原因不多说啦.所以要把数据放到Elasticsearch中进行快速的搜索,这是便产生了一个数据迁移的需求, ...

  3. 【Canal】数据同步的终极解决方案,阿里巴巴开源的Canal框架当之无愧!!

    写在前面 在当今互联网行业,尤其是现在分布式.微服务开发环境下,为了提高搜索效率,以及搜索的精准度,会大量使用Redis.Memcached等NoSQL数据库,也会使用大量的Solr.Elastics ...

  4. 实战!Spring Boot 整合 阿里开源中间件 Canal 实现数据增量同步!

    大家好,我是不才陈某~ 数据同步一直是一个令人头疼的问题.在业务量小,场景不多,数据量不大的情况下我们可能会选择在项目中直接写一些定时任务手动处理数据,例如从多个表将数据查出来,再汇总处理,再插入到相 ...

  5. Canal 同步异常分析:Could not find first log file name in binary log index file

    文章首发于[博客园-陈树义],点击跳转到原文Canal同步异常分析:Could not find first log file name in binary log index file. 公司搜索相 ...

  6. mysql 同步数据到 ElasticSearch 的方案

    MySQL Binlog 要通过 MySQL binlog 将 MySQL 的数据同步给 ES, 我们只能使用 row 模式的 binlog.如果使用 statement 或者 mixed forma ...

  7. Mysql通过Canal同步Elasticsearch

    目录 版本管理 Mysql 设置 在MySQL配置文件my.cnf设置: 检查是否开启 增加新用户: 安装 Elasticsearch es 跨域问题 目录挂载 安装 Elasticsearch-He ...

  8. 实现从Oracle增量同步数据到GreenPlum

    简介: GreenPlum是一个基于PostgreSQL数据库开发的MPP架构的数据库仓库,适用于OLAP系统,支持50PB(1PB=1000TB)级海量数据的存储和处理. 背景: 目前有一个业务是需 ...

  9. sql笨办法同步数据

    Helpers.SqlHelper sqlHelper = new Helpers.SqlHelper("server=***;database=Cms;user id=sa;passwor ...

  10. 对Big Table进行全表更新,导致 Replication 同步数据的过程十分缓慢

    在Publisher database中更新一个big table,数据行数是3.4亿多.由于没有更新 clustered Index key,因此,只产生了3.4亿多个Update Commands ...

随机推荐

  1. Go runtime 调度器精讲(十一):总览全局

    原创文章,欢迎转载,转载请注明出处,谢谢. 0. 前言 前面用了十讲介绍了 Go runtime 调度器,这一讲结合一些图在总览下 Go runtime 调度器. 1. 状态转换图 首先是 Gorou ...

  2. dfs与贪心算法——洛谷5194

    问题描述: 有n个砝码,将砝码从大到小排列,从第三个砝码开始,所有砝码均大于其前两个砝码之和,问怎样的砝码组合才可以组合出不大于c的最大重量,输出该重量 输入: 第一行输入两个个整数N,c,代表有N个 ...

  3. [namespace hdk] ordered_vector

    功能: 已重载[]运算符 已重载+运算符(合并) 已重载+=运算符 已重载构造函数 clear() it() 以std::vector形式返回自身 print(char=' ',char='\n') ...

  4. 在 ArkTS 中,如何有效地进行内存管理和避免内存泄漏?

    ArkTS 是鸿蒙生态的应用开发语言,它在 TypeScript 的基础上进行了优化和定制,以适应鸿蒙系统的需求. 以下是在 ArkTS 中进行有效的内存管理和避免内存泄漏: 1. 使用 const ...

  5. Windows平台下安装与配置MySQL9

    要在Windows平台下安装MySQL,可以使用图行化的安装包.图形化的安装包提供了详细的安装向导,以便于用户一步一步地完成对MySQL的安装.本节将详细介绍使用图形化安装包安装MySQL的方法. 1 ...

  6. CPU缓存伪共享

    CPU缓存什么东西?当然这个问题很多人有可能觉得比较傻,CPU缓存什么,肯定是缓存数据(代码)啊,要不然还能缓存啥,这个确实没问题,但是CPU到底缓存什么样的数据呢?因为对CPU来说,无论是指令,还是 ...

  7. Linux内核虚拟内存管理之匿名映射缺页异常分析

    今天我们就来讨论下这种缺页异常,让大家彻底理解它.注:本文使用linux-5.0内核源代码.文章分为以下几节内容: 匿名映射缺页异常的触发情况 0页是什么?为什么使用0页? 源代码分析 3.1 触发条 ...

  8. day05-JDK的卸载与安装

    JDK卸载 右键我的电脑--属性--高级系统设置--环境变量,找到JAVA_HOME安装目录,删除Java安装目录 删除JAVA_HOME 删除path下关于java的目录 cmd查看Java -ve ...

  9. 云原生周刊:Kubernetes v1.29 正式发布 | 2023.12.18

    开源项目推荐 Robusta KRR Robusta KRR(Kubernetes Resource Recommender)是一个用于优化 Kubernetes 集群中资源分配的 CLI 工具.它从 ...

  10. Unity 华为快游戏JS桥接 实现写日志等功能

    之前接入微信小游戏本身代码js桥接比较完善,抖音小游戏有缺少但也没缺的这么多,华为这边的API,大残啊!官方转换插件Github仓库上一次提交在3月份.(截至现在)API给的很简略,接入js代码那里说 ...