阿里Canal安装和代码示例
Canal的简单使用
canal可以用来监控数据库数据的变化,从而获得新增数据,或者修改的数据,用于实际工作中,比较实用,特此记录一下
Canal简介
canal是应阿里巴巴存在杭州和美国的双机房部署,存在跨机房同步的业务需求而提出的。
阿里系公司开始逐步的尝试基于数据库的日志解析,获取增量变更进行同步,由此衍生出了增量订阅&消费的业务
基于日志增量订阅&消费支持的业务:
数据库镜像
数据库实时备份
多级索引 (卖家和买家各自分库索引)
search build
业务cache刷新
价格变化等重要业务消息
keyword:数据库同步,增量订阅&消费。
首先,下载canal安装包:
https://github.com/alibaba/canal/releases

安装步骤:
在opt下(或者其他目录)创建一个canal文件夹

因为canal解压后并没有整体的文件夹,是把里面的内容一下解压出来的
然后进入canal文件夹,将安装包canal.deployer-1.0.24.tar.gz传输进来
解压:
tar -zxvf canal.deployer-1.0..tar.gz

可以删除安装包canal.deployer-1.0.24.tar.gz了
修改canal配置文件
vi conf/example/instance.properties

修改红框内的内容
canal.instance.dbUsername = **** #数据库用户名
canal.instance.dbPassword = **** #数据库密码
canal.instance.defaultDatabaseName = **** #指定需要同步的数据库
canal.instance.connectionCharset = UTF-8 #指定编码方式
然后保存:
esc :wq
配置mysql数据库
vi /etc/my.cnf
添加以下三行内容,如果原来存在,则不需要添加,只需对当前配置项进行修改即可
log-bin=mysql-bin #添加这一行就ok
binlog-format=ROW #选择row模式
server-id=1 #配置mysql replaction需要定义,不能和canal的slaveId重复

然后保存:
esc :wq
配置canal用户
用root用户登录mysql:
mysql -uroot -p
回车,输入密码
创建“canal”用户:
create user canal identified by 'canal';
有可能会出现如下情况:

直接刷新:
FLUSH PRIVILEGES;
然后再次创建“canal”用户

为“canal”用户赋予相应权限:
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
然后刷新权限:
FLUSH PRIVILEGES;
退出mysql
exit;
重启mysql服务
sudo service mysqld restart

cd到bin目录,启动canal-server
cd bin/ ./startup.sh
查看启动状态:
tail -f -n ../logs/canal/canal.log

用客户端代码进行检测
package com.test; import java.net.InetSocketAddress;
import java.util.List; import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.protocol.CanalEntry.Column;
import com.alibaba.otter.canal.protocol.CanalEntry.Entry;
import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;
import com.alibaba.otter.canal.protocol.CanalEntry.EventType;
import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;
import com.alibaba.otter.canal.protocol.CanalEntry.RowData;
import com.alibaba.otter.canal.protocol.Message; public class TestCanal { public static void main(String args[]) {
// 创建链接
CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("***canal所在的主机ip***", 11111),
"example", "", "");
int batchSize = 1000;
int emptyCount = 0;
try {
connector.connect();
connector.subscribe(".*\\..*");
connector.rollback();
int totalEmtryCount = 1200;
while (emptyCount < totalEmtryCount) {
Message message = connector.getWithoutAck(batchSize); // 获取指定数量的数据
long batchId = message.getId();
int size = message.getEntries().size();
if (batchId == -1 || size == 0) {
emptyCount++;
// System.out.println("empty count : " + emptyCount);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
emptyCount = 0;
// System.out.printf("message[batchId=%s,size=%s] \n", batchId, size);
printEntry(message.getEntries());
} connector.ack(batchId); // 提交确认
// connector.rollback(batchId); // 处理失败, 回滚数据
} System.out.println("empty too many times, exit");
} finally {
connector.disconnect();
}
} private static void printEntry(List<Entry> entrys) {
for (Entry entry : entrys) {
if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN
|| entry.getEntryType() == EntryType.TRANSACTIONEND) {
continue;
} RowChange rowChage = null;
try {
rowChage = RowChange.parseFrom(entry.getStoreValue());
} catch (Exception e) {
throw new RuntimeException("ERROR ## parser of eromanga-event has an error , data:" + entry.toString(),
e);
} EventType eventType = rowChage.getEventType();
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)); for (RowData rowData : rowChage.getRowDatasList()) {
if (eventType == EventType.DELETE) {
printColumn(rowData.getBeforeColumnsList());
} else if (eventType == 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<Column> columns) {
for (Column column : columns) {
System.out.println(column.getName() + " : " + column.getValue() + " update=" + column.getUpdated());
}
} }
直接启动mian函数

然后任意选择一张表,插入数据库一条数据

控制台输出内容

更多信息可以参考:
谈谈对Canal( 增量数据订阅与消费 )的理解
http://www.importnew.com/25189.html
https://blog.csdn.net/my201110lc/article/details/78836270
阿里Canal安装和代码示例的更多相关文章
- 阿里云PHP Redis代码示例
测试代码示例 <?php /* 这里替换为连接的实例host和port */ $host = "localhost"; $port = 6379; /* 这里替换为实例id和 ...
- Android获取Root权限之后的静默安装实现代码示例分析
转:http://blog.csdn.net/jiankeufo/article/details/43795015 Adroid开发中,我们有时会遇到一些特殊功能的实现,有些功能并没有太高技术难度,但 ...
- 阿里Canal框架数据库同步-实战教程
一.Canal简介: canal是阿里巴巴旗下的一款开源项目,纯Java开发.基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB). 二.背景介绍: ...
- 阿里Canal中间件的初步搭建和使用
一.前言 Binlog是MySQL数据库的二进制日志,用于记录用户对数据库操作的SQL语句(除了数据查询语句)信息.而Binlog格式也有三种,分别为STATEMENT.ROW.MIXED.STATM ...
- Thrift在Windows及Linux平台下的安装和使用示例
本文章也同时发表在个人博客Thrift在Windows及Linux平台下的安装和使用示例上. thrift介绍 Apache Thrift 是 Facebook 实现的一种高效的.支持多种编程语言的R ...
- Ruby入门--Linux/Windows下的安装、代码开发及Rails实战
Ruby入门--Linux/Windows下的安装.代码开发及Rails实战 http://www.linuxidc.com/Linux/2014-04/100242.htm Ubuntu 13.04 ...
- 天气类API调用的代码示例合集:全国天气预报、实时空气质量数据查询、PM2.5空气质量指数等
以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 全国天气预报:数据来自国家气象局,可根据地名.经纬度GPS.IP查 ...
- 位置信息类API调用的代码示例合集:中国省市区查询、经纬度地址转换、POI检索等
以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 中国省市区查询:2017最新中国省市区地址 经纬度地址转换:经纬度 ...
- 通讯服务类API调用的代码示例合集:短信服务、手机号归属地查询、电信基站查询等
以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 短信服务:通知类和验证码短信,全国三网合一通道,5秒内到达,费用低 ...
随机推荐
- css奇淫巧计
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- Docker & Consul & Fabio & ASP.NET Core 2.0 微服务跨平台实践
相关博文: Ubuntu 简单安装 Docker Mac OS.Ubuntu 安装及使用 Consul Consul 服务注册与服务发现 Fabio 安装和简单使用 阅读目录: Docker 运行 C ...
- Java基础15:深入剖析Java枚举类
更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...
- Java开发知识之Java数组
Java开发知识之Java数组 一丶数组简介 首先,不管是Java 还是 C++ 还是其它语言.都有数组. (有可能叫法不同) 数组简而言之就是存储一段连续相同数据类型的数据结构 在Java中数组可以 ...
- 执行对象Statement、PreparedStatement和CallableStatement详解 JDBC简介(五)
执行对象是SQL的执行者,SQL是“安排好的任务”,执行对象就是“实际工作的人”. 执行对象有三种: Statement.PreparedStatement和CallableStatement,他们都 ...
- [二十]JavaIO之StringReader 与 StringWriter
功能简介 还记得前面说过的CharArrayReader 和 CharArrayWriter吗? CharArray 是数据源 CharArrayReader 是读, 从一个CharArray 中读 ...
- .NetCore部署至IIS
部署教程 操作系统要求 Windows 7 或更高版本 Windows Server 2008 R2 或更高版本 依赖的组件 Runtime & Hosting Bundle 可以选择.NET ...
- webpack4.0各个击破(5)—— Module篇
webpack4.0各个击破(5)-- Module篇 webpack作为前端最火的构建工具,是前端自动化工具链最重要的部分,使用门槛较高.本系列是笔者自己的学习记录,比较基础,希望通过问题 + 解决 ...
- .NetCore教程之 EFCore连接Mysql DBFirst模式
一:创建EF的类库,同时将此项目设置为启动项(为Scaffold-DbContext -tables指令使用),同时安装2个包 ①Microsoft.EntityFrameworkCore.Too ...
- Java开发笔记(三十三)字符包装类型
正如整型int有对应的包装整型Integer那样,字符型char也有对应的包装字符型Character.初始化字符包装变量也有三种方式,分别是:直接用等号赋值.调用包装类型的valueOf方法.使用关 ...