什么是Canal (卡耐尔) ?

Canal 是用 Java 开发的基于数据库增量日志解析,提供增量数据订阅&消费的中间件
原理基于MySQL的binlog从库监听
 
 
 

一、MySQL环境配置

1、更改MySQL配置 (my.ini / my.cnf):

[mysqld]

# 主库id标识
server-id=1 # 开启binlog日志
log-bin=mysql-bin # 日志格式类型
binlog_format=row # (可选)声明只对哪个库进行日志输出
binlog-do-db=gmall-2021

2、测试用例

没有表就创建一个测试用的表:

CREATE TABLE user_info(
  `id` VARCHAR(255),
  `name` VARCHAR(255),
  `sex` VARCHAR(255)
);

3、监听的账号

和主从复制一样,需要提供一个从库监听的账号:

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

二、安装Canal

Linux平台:

# 解压方式一
tar -zxvf canal.deployer-1.1.2.tar.gz mkdir canal.deployer-1.1.2 mv bin canal.deployer-1.1.2/
mv logs canal.deployer-1.1.2/
mv lib canal.deployer-1.1.2/
mv conf canal.deployer-1.1.2/ # 解压方式二
mkdir ~/canal-1.1.2
tar -zxvf canal.deployer-1.1.2.tar.gz -C ~/canal-1.1.2/

Windows平台:

新建一个canal的目录,然后打开目录
把压缩包内容解压到目录中即可

通用配置操作:

案例只是为了演示,单机运行的方式进行配置

# 备份 instance.properties文件
cd ~/canal-1.1.2/example
cp instance.properties instance.properties.bak

编辑example下的实例文件

vim ~/canal-1.1.2/conf/example/instance.properties

关键参数项:

# 伪装从库的id,不要和主库id一致即可
canal.instance.mysql.slaveId=20
# 主库IP地址和端口号
canal.instance.master.address=192.168.2.225:3308
# 主库开设的监听账号
canal.instance.dbUsername=canal
canal.instance.dbPassword=123456
# 字符集
canal.instance.connectionCharset=UTF-8
# 默认监听的db?
canal.instance.defaultDatabaseName=canal

三、启动,关闭Canal

restart.sh
startup.bat
startup.sh
stop.sh # windows 平台直接运行 startup.bat
# 关闭就是直接关闭终端窗口即可
startup.bat # linux 平台
startup.
sh # 启动
restart.sh # 重启
stop.sh # 停止

四、创建Canal监听客户端:

canal没有提供默认的终端输出,强制要求客户端监听日志消息:

这里使用Java做一个客户端来查看消息

创建普通Maven项目,引入两个依赖

<dependencies>
<dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.client</artifactId>
<version>1.1.2</version>
</dependency> <dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-clients</artifactId>
<version>2.4.1</version>
</dependency>
</dependencies>

客户端类:

import com.alibaba.fastjson.JSONObject;
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 com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException; import java.net.InetSocketAddress;
import java.util.List; public class CanalClient { public static void main(String[] args) throws InterruptedException, InvalidProtocolBufferException { //TODO 获取连接
CanalConnector canalConnector = CanalConnectors.newSingleConnector(new InetSocketAddress("127.0.0.1", 11111), "example", "", ""); while (true) { //TODO 连接
canalConnector.connect(); //TODO 订阅数据库
canalConnector.subscribe("canal.*"); //TODO 获取数据
Message message = canalConnector.get(100); //TODO 获取Entry集合
List<CanalEntry.Entry> entries = message.getEntries(); //TODO 判断集合是否为空,如果为空,则等待一会继续拉取数据
if (entries.size() <= 0) {
System.out.println("当次抓取没有数据,休息一会。。。。。。");
Thread.sleep(1000);
} else { //TODO 遍历entries,单条解析
for (CanalEntry.Entry entry : entries) { //1.获取表名
String tableName = entry.getHeader().getTableName(); //2.获取类型
CanalEntry.EntryType entryType = entry.getEntryType(); //3.获取序列化后的数据
ByteString storeValue = entry.getStoreValue(); //4.判断当前entryType类型是否为ROWDATA
if (CanalEntry.EntryType.ROWDATA.equals(entryType)) { //5.反序列化数据
CanalEntry.RowChange rowChange = CanalEntry.RowChange.parseFrom(storeValue); //6.获取当前事件的操作类型
CanalEntry.EventType eventType = rowChange.getEventType(); //7.获取数据集
List<CanalEntry.RowData> rowDataList = rowChange.getRowDatasList(); //8.遍历rowDataList,并打印数据集
for (CanalEntry.RowData rowData : rowDataList) { JSONObject beforeData = new JSONObject();
List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();
for (CanalEntry.Column column : beforeColumnsList) {
beforeData.put(column.getName(), column.getValue());
} JSONObject afterData = new JSONObject();
List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();
for (CanalEntry.Column column : afterColumnsList) {
afterData.put(column.getName(), column.getValue());
} //数据打印
System.out.println("Table:" + tableName +
",EventType:" + eventType +
",Before:" + beforeData +
",After:" + afterData);
}
} else {
System.out.println("当前操作类型为:" + entryType);
}
}
}
}
}
}

开启后,想指定的表中写入数据:

客户端输出消息:

当次抓取没有数据,休息一会。。。。。。
当次抓取没有数据,休息一会。。。。。。
当次抓取没有数据,休息一会。。。。。。
当次抓取没有数据,休息一会。。。。。。
当前操作类型为:TRANSACTIONBEGIN
Table:user_info,EventType:INSERT,Before:{},After:{
"sex":"男","name":"张三","id":"1"}
当前操作类型为:TRANSACTIONEND
当前操作类型为:TRANSACTIONBEGIN
Table:user_info,EventType:INSERT,Before:{},After:{"sex":"男","name":"张三","id":"2"
}
当前操作类型为:TRANSACTIONEND

当次抓取没有数据,休息一会。。。。。。

五、Kafka模式

修改 canal.properties
# 指定输出模式为kafka
canal.serverMode = kafka # kafka集群地址,如单机,则写一个即可
canal.mq.servers = hadoop102:9092,hadoop103:9092,hadoop104:9092

修改 example/instance.properties

# mq config
# 指定Topic名称 和 分区数量
canal.mq.topic=canal_test
canal.mq.partitionsNum=1

重启canal以加载配置信息

启动Kafka消费者来查看是否运行:

bin/kafka-console-consumer.sh --bootstrap-server hadoop102:9092 --topic canal_test

执行插入SQL:

INSERT INTO user_info VALUES('1001','zhangsan','male'),('1002','lisi','female');

Kafka控制台:

{
"data": [
{
"id": "1001",
"name": "zhangsan",
"sex": "male"
},
{
"id": "1002",
"name": "lisi",
"sex": "female"
}
],
"database": "gmall-2021",
"es": 1639360729000,
"id": 1,
"isDdl": false,
"mysqlType": {
"id": "varchar(255)",
"name": "varchar(255)",
"sex": "varchar(255)"
},
"old": "null",
"sql": "",
"sqlType": {
"id": 12,
"name": 12,
"sex": 12
},
"table": "user_info",
"ts": 1639361038454,
"type": "INSERT"
}
 
 

【Canal】01 入门 & Kafka模式的更多相关文章

  1. Python学习--01入门

    Python学习--01入门 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.和PHP一样,它是后端开发语言. 如果有C语言.PHP语言.JAVA语言等其中一种语言的基础,学习Py ...

  2. 设计模式入门,策略模式,c++代码实现

    // test01.cpp : Defines the entry point for the console application.////第一章,设计模式入门,策略模式#include &quo ...

  3. [译]Vulkan教程(01)入门

    [译]Vulkan教程(01)入门 接下来我将翻译(https://vulkan-tutorial.com)上的Vulkan教程.这可能是我学习Vulkan的最好方式,但不是最理想的方式. 我会用“d ...

  4. 「从零单排canal 01」 canal 10分钟入门(基于1.1.4版本)

    1.简介 canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据 订阅 和 消费.应该是阿里云DTS(Data Transfer Servi ...

  5. Canal详细入门实战(使用总结)

    Canal介绍 Canal简介 canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费 早期阿里巴巴因为杭州和美国双机房部署,存在 ...

  6. RabbitMQ入门-Topic模式

    上篇<RabbitMQ入门-Routing直连模式>我们介绍了可以定向发送消息,并可以根据自定义规则派发消息.看起来,这个Routing模式已经算灵活的了,但是,这还不够,我们还有更加多样 ...

  7. elasticsearch6.7 01.入门指南(2)

    2.安装(略) 默认情况下,elasticsearch 使用端口 9200 来访问它的 REST API.如果有必要,该端口也可以配置 3.探索集群 3.1 The REST API 既然我们已经启动 ...

  8. 带你入门代理模式/SpringAop的运行机制

    SpringAop 是spring框架中最重要的一项功能之一,同时也是企业级开发记录事物日志等不可或缺的一部分,如果说你的系统需要记录用户访问接口的操作,那SpringAop是很完美的了,当然,拦截器 ...

  9. canal 环境搭建 kafka Zookeeper安装(二)

    第一步 创建Zookeeper 下载完成后 修改 Zookeeper中的 zoo.cfg 修改 dataDir .dataLogDir 集群模式 server.1=ServerIP:2888:3888 ...

  10. Spring Cloud - Nacos注册中心入门单机模式及集群模式

    近几年微服务很火,Spring Cloud提供了为服务领域的一整套解决方案.其中Spring Cloud Alibaba是我们SpringCloud的一个子项目,是提供微服务开发的一站式解决方案. 包 ...

随机推荐

  1. linux的账号和组

    1.0 账号与用户组 1.1 用户标识符:UID,GID 虽然我们登陆Linux主机的时候输入的是账号,但其实Linux主机并不会直接认识你的账号名称,账号只是为了方便人. 一个文件如何判断他的拥有者 ...

  2. react css-in-js

    CSS-in-JS是一种技术,而不是一个具体的库实现.简单来说CSS-in-JS就是将应用的CSS样式写在JavaScript文件里面,而不是独立为一些css,scss或less之类的文件,这样你就可 ...

  3. OpenCV简单实现AR需用到的算法函数介绍

    目前的AR需求(想要达到的目标) 公司目前的需求是要能够指定一个物体开始追踪,将一张预先准备好的图像覆盖在被追踪的物体上, 然后镜头偏转缩放各类操作,再转回来仍然可以识别到,并且同样依旧覆盖图片到先前 ...

  4. Codeforces Round 923 (Div. 3) 比赛记录

    Codeforces Round 923 (Div. 3) 这是我第二次参加 cf阴间场. 10 minutes ago: 这次报名人数超过 4 万,一开始网站就崩溃了,比赛延迟了 10 分钟..开局 ...

  5. The requested operation cannot be completed because the connection has been broken

    具体报错 The requested operation cannot be completed because the connection has been broken. -- xxxForyy ...

  6. Vue学习:13.生命周期综合

    0基础如何进入IT行业? 简介:对于没有任何相关背景知识的人来说,如何才能成功进入IT行业?是否有一些特定的方法或技巧可以帮助他们实现这一目标? 方向一:学习路径 明确兴趣和目标:首先确定你对IT领域 ...

  7. 导出excel文件接口代码示例

    导出excel文件接口代码示例 1.该导出接口,token不能通过请求头来传输,需要在get请求的参数中带出来2.验证token的方法除了在拦截器中统一拦截,针对get接口传参数的方式也需要单独在接口 ...

  8. linux查看redis安装路径

    ## linux查看redis安装路径 redis-cli -h 127.0.0.1 -p 6379redis-cli monitor > redis2.log /usr/local/redis ...

  9. Python中的常见方法

    Python中有三种比较常见的方法类型,如类方法和静态方法,实例方法,他们是面向对象编程中重要的概念. 1.类方法 类方法是通过使用装饰器@classmethod来定义的,他的第一个参数是cls,指向 ...

  10. 《Node.js+Vue.js+MangoDB全栈开发实战》已出版

    <Node.js+Vue.js+MangoDB全栈开发实战> 图书购买地址: 京东:<Node.js+Vue.js+MangoDB全栈开发实战> 当当:<Node.js+ ...