【Canal】01 入门 & Kafka模式
什么是Canal (卡耐尔) ?
一、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模式
# 指定输出模式为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模式的更多相关文章
- Python学习--01入门
Python学习--01入门 Python是一种解释型.面向对象.动态数据类型的高级程序设计语言.和PHP一样,它是后端开发语言. 如果有C语言.PHP语言.JAVA语言等其中一种语言的基础,学习Py ...
- 设计模式入门,策略模式,c++代码实现
// test01.cpp : Defines the entry point for the console application.////第一章,设计模式入门,策略模式#include &quo ...
- [译]Vulkan教程(01)入门
[译]Vulkan教程(01)入门 接下来我将翻译(https://vulkan-tutorial.com)上的Vulkan教程.这可能是我学习Vulkan的最好方式,但不是最理想的方式. 我会用“d ...
- 「从零单排canal 01」 canal 10分钟入门(基于1.1.4版本)
1.简介 canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据 订阅 和 消费.应该是阿里云DTS(Data Transfer Servi ...
- Canal详细入门实战(使用总结)
Canal介绍 Canal简介 canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费 早期阿里巴巴因为杭州和美国双机房部署,存在 ...
- RabbitMQ入门-Topic模式
上篇<RabbitMQ入门-Routing直连模式>我们介绍了可以定向发送消息,并可以根据自定义规则派发消息.看起来,这个Routing模式已经算灵活的了,但是,这还不够,我们还有更加多样 ...
- elasticsearch6.7 01.入门指南(2)
2.安装(略) 默认情况下,elasticsearch 使用端口 9200 来访问它的 REST API.如果有必要,该端口也可以配置 3.探索集群 3.1 The REST API 既然我们已经启动 ...
- 带你入门代理模式/SpringAop的运行机制
SpringAop 是spring框架中最重要的一项功能之一,同时也是企业级开发记录事物日志等不可或缺的一部分,如果说你的系统需要记录用户访问接口的操作,那SpringAop是很完美的了,当然,拦截器 ...
- canal 环境搭建 kafka Zookeeper安装(二)
第一步 创建Zookeeper 下载完成后 修改 Zookeeper中的 zoo.cfg 修改 dataDir .dataLogDir 集群模式 server.1=ServerIP:2888:3888 ...
- Spring Cloud - Nacos注册中心入门单机模式及集群模式
近几年微服务很火,Spring Cloud提供了为服务领域的一整套解决方案.其中Spring Cloud Alibaba是我们SpringCloud的一个子项目,是提供微服务开发的一站式解决方案. 包 ...
随机推荐
- linux的账号和组
1.0 账号与用户组 1.1 用户标识符:UID,GID 虽然我们登陆Linux主机的时候输入的是账号,但其实Linux主机并不会直接认识你的账号名称,账号只是为了方便人. 一个文件如何判断他的拥有者 ...
- react css-in-js
CSS-in-JS是一种技术,而不是一个具体的库实现.简单来说CSS-in-JS就是将应用的CSS样式写在JavaScript文件里面,而不是独立为一些css,scss或less之类的文件,这样你就可 ...
- OpenCV简单实现AR需用到的算法函数介绍
目前的AR需求(想要达到的目标) 公司目前的需求是要能够指定一个物体开始追踪,将一张预先准备好的图像覆盖在被追踪的物体上, 然后镜头偏转缩放各类操作,再转回来仍然可以识别到,并且同样依旧覆盖图片到先前 ...
- Codeforces Round 923 (Div. 3) 比赛记录
Codeforces Round 923 (Div. 3) 这是我第二次参加 cf阴间场. 10 minutes ago: 这次报名人数超过 4 万,一开始网站就崩溃了,比赛延迟了 10 分钟..开局 ...
- 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 ...
- Vue学习:13.生命周期综合
0基础如何进入IT行业? 简介:对于没有任何相关背景知识的人来说,如何才能成功进入IT行业?是否有一些特定的方法或技巧可以帮助他们实现这一目标? 方向一:学习路径 明确兴趣和目标:首先确定你对IT领域 ...
- 导出excel文件接口代码示例
导出excel文件接口代码示例 1.该导出接口,token不能通过请求头来传输,需要在get请求的参数中带出来2.验证token的方法除了在拦截器中统一拦截,针对get接口传参数的方式也需要单独在接口 ...
- linux查看redis安装路径
## linux查看redis安装路径 redis-cli -h 127.0.0.1 -p 6379redis-cli monitor > redis2.log /usr/local/redis ...
- Python中的常见方法
Python中有三种比较常见的方法类型,如类方法和静态方法,实例方法,他们是面向对象编程中重要的概念. 1.类方法 类方法是通过使用装饰器@classmethod来定义的,他的第一个参数是cls,指向 ...
- 《Node.js+Vue.js+MangoDB全栈开发实战》已出版
<Node.js+Vue.js+MangoDB全栈开发实战> 图书购买地址: 京东:<Node.js+Vue.js+MangoDB全栈开发实战> 当当:<Node.js+ ...