Canal的简单使用(监控数据库数据的变化)
原文:https://www.cnblogs.com/java-spring/p/8930740.html
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.24.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 50 ../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的简单使用(监控数据库数据的变化)的更多相关文章
- 监控SQL:通过SQL Server的DDL触发器来监控数据库结构的变化(1)
原文:监控SQL:通过SQL Server的DDL触发器来监控数据库结构的变化(1) 如果你要同步不同数据库之间的数据,首先会想到的是数据库复制技术,但如果让你同步数据库的结构,你会想到什么呢? 下面 ...
- 用Maven整合SpringMVC+Spring+Hibernate 框架,实现简单的插入数据库数据功能
一.搭建開始前的准备 1.我用的MyEclipse2014版,大家也能够用IDEA. 2.下载Tomcat(免安装解压包).MySQL(zip包下载地址 免安装解压包,优点就是双击启动,最后我会把ba ...
- sqlDependency监控数据库数据变化,自动通知
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- C#简单代码转移数据库数据
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Data;u ...
- postgreSQL数据库的监控及数据维护
目前postgreSQL数据库的管理,数据查询等都需要安装postgreSQL软件或安装pgadmin等,远程访问都需要先登录到服务器等繁琐的操作.如果是开发团队,那么每个开发,测试,管理人员都要经历 ...
- Oracle数据库的监控及数据维护
目前Oracle数据库的管理,数据查询等都需要安装Oracle软件或安装Oracle Client等,远程访问都需要先登录到服务器等繁琐的操作.如果是开发团队,那么每个开发,测试,管理人员都要经历这个 ...
- solr 简单搭建 数据库数据同步(待续)
原来在别的公司负责过文档检索模块的维护(意思就是不是俺开发的啦). 所以就略微接触和研究了下文档检索. 文档检索事实上是全文检索.是通过一种技术把N多文档进行一定规律的分割归类,然后创建易于搜索的索引 ...
- 数据库数据在Java占用内存简单估算
数据库数据在Java占用内存简单估算 结论: 1.数据库记录放在JAVA里,用对象(ORM一般的处理方式)须要4倍左右的内存空间.用HashMap这样的KV保存须要10倍空间; 2.假设你主要数据是t ...
- Postgresql数据库数据简单的导入导出
Postgresql数据库数据简单的导入导出 博客分类: DataBase postgres 命令操作: 数据的导出:pg_dump -U postgres(用户名) (-t 表名) 数据库名( ...
随机推荐
- 理解ADFS相关概念
核心概念 Claims是?Token是?Security Token是?Security Token Server (STS)是? 声明与令牌无关,但通过封装在安全令牌中来进行网络传输! SSL证书是 ...
- WordPress简洁的SEO标题、关键词和描述
WordPress标题.关键词和描述,之所以简洁,那是站在SEO的角度来考虑的. 首先,现在关键词这个标签早已被搜索引擎扔进历史的垃圾堆,所以这个keywords标签已经没用了,不写也罢. 其次,描述 ...
- 阿里云ecs自动创建快照教程
最近在一个博客联盟的微信群里面看到经常有朋友问阿里云的ecs服务器怎么设置自动创建快照,也不知道最近是怎么了,看到问这个问题的朋友有有四五个左右了,今天就特意到博客里来费大家分享设置自动创建快照的方法 ...
- Java基础系列-substring的原理
原创文章,转载请标注出处:https://www.cnblogs.com/V1haoge/p/10755235.html JDK 6和JDK 7中substring的原理及区别 substring(i ...
- Mac brew命令踩坑
brew是mac上的在线包管理软件,相当于linux apt以及yum包管理工具 1.取消brew的自动更新(https://blog.csdn.net/yf9595/article/details/ ...
- eclipse设置html js css自动提示
eclipse也可以像Visual Studio 2008那样完全智能提示HTML/JS/CSS代码,使用eclipse自带的插件,无需另外安装插件,具体步骤如下 1.打开eclipse→Window ...
- GB和GIB的区别
天啦撸,这么多年才知道这个东西! Gibibyte(giga binary byte)是信息或计算机硬盘存储的一个单位,简称GiB.由来“GiB”,“KiB”,“MiB”等是于1999年由国际电工协会 ...
- 1、6 登陆 通过name 查到一个对象,如果没有。提示用户名不存在,再将查到的pwd 加传过来的pwd(需要加密)比较
@RequestMapping("/login") public Object login(Student student) { Student s=studentService. ...
- [转帖]从壹开始前后端分离【重要】║最全的部署方案 & 最丰富的错误分析
从壹开始前后端分离[重要]║最全的部署方案 & 最丰富的错误分析 https://www.cnblogs.com/laozhang-is-phi/p/beautifulPublish-most ...
- git简易指南
目录 工作流 初始化仓库 查看分支 添加和提交 推送改动 分支 重命名分支 更新与合并 替换本地改动 回滚 远程仓库 有用的贴士 GIT vs SVN 工作流 你的本地仓库由 git 维护的三棵&qu ...