监听mysql表内容变化 使用canal_2 监听mysql表内容变化,使用canal
mysql本身是支持主从的(master slave),原理就是master产生的binlog日志记录了所有的增删改语句,将binlog发送到slave节点进行执行即可完成数据的同步。
canal是阿里开源的一个中间件,它就是通过解析binlog来完成数据变更的监听的。
https://github.com/alibaba/canal
可以看到,canal是这样工作的:canal有一个server工程,该server自己伪装为mysql的一个slave节点,然后向master请求所有的变更日志。同时canal有一个client工程,通过添加client的sdk,我们就可以在项目里监听到server端传来的数据变更信息,从而达到监听数据变化的目的。
安装配置canal
在这里https://github.com/alibaba/canal/releases,下载canal releases包,如https://github.com/alibaba/canal/releases/download/canal-1.0.22/canal.deployer-1.0.22.tar.gz。
这个就是server端,下载后解压,如图
打开conf/example下的instance.properties文件,编辑#################################################
## mysql serverId
canal.instance.mysql.slaveId = 1234
# position info
canal.instance.master.address = 127.0.0.1:3306
canal.instance.master.journal.name =
canal.instance.master.position =
canal.instance.master.timestamp =
#canal.instance.standby.address =
#canal.instance.standby.journal.name =
#canal.instance.standby.position =
#canal.instance.standby.timestamp =
# username/password
canal.instance.dbUsername = canal
canal.instance.dbPassword = canal
canal.instance.defaultDatabaseName = test
canal.instance.connectionCharset = UTF-8
# table regex
canal.instance.filter.regex = .*\\..*
# table black regex
canal.instance.filter.black.regex =
#################################################
address设置为mysql的连接地址,defaultDatabaseName设置为自己要监听的库名,如test。
在mysql命令行,创建一个新用户,作为slaveCREATE USER canal IDENTIFIED BY 'canal';
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
-- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ;
FLUSH PRIVILEGES;
对应配置文件里的canal用户。到此配置完毕。
执行bin目录下的startup.sh
启动后可以在logs目录下查看日志。在example目录下的example.log,如果没有报错,说明启动成功。
canal客户端编写
服务端启动完毕后,在客户端即可监听test库的变化。
新建一个java maven项目,pom.xml里添加依赖
com.alibaba.otter
canal.client
1.0.12
package com.mindata;
import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.common.utils.AddressUtils;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.alibaba.otter.canal.protocol.Message;
import java.net.InetSocketAddress;
import java.util.List;
/**
* A Camel Application
*/
public class MainApp {
/**
* A main() so we can easily run these routing rules in our IDE
*/
public static void main(String... args) throws Exception {
// 创建链接
CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress(AddressUtils.getHostIp(),
11111), "example", "", "");
int batchSize = 1000;
int emptyCount = 0;
try {
connector.connect();
connector.subscribe(".*\\..*");
connector.rollback();
int totalEmptyCount = 120;
while (emptyCount < totalEmptyCount) {
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) {
}
} 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 entrys) {
for (CanalEntry.Entry entry : entrys) {
if (entry.getEntryType() == CanalEntry.EntryType.TRANSACTIONBEGIN || entry.getEntryType() == CanalEntry
.EntryType
.TRANSACTIONEND) {
continue;
}
CanalEntry.RowChange rowChage = null;
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);
}
CanalEntry.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 (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 columns) {
for (CanalEntry.Column column : columns) {
System.out.println(column.getName() + " : " + column.getValue() + " update=" + column.getUpdated());
}
}
}
注意newSingleConnector那里,设置canal server的ip和端口,端口默认为11111。example是和conf目录下的相对应。
如果你在这里新建个目录abc,目录里也放一个instance.properties,那么就可以在客户端监听abc。
启动客户端,查看控制台输出。
启动后,就可以打印empty count,此时你可以操作数据库里的test库,做任何增删改的操作,然后就能在控制台看到打印的语句。
可以看到,修改的是test库里的History表,before代表修改前,id=3,calltime字段值为3,after修改后,calltime为22.customer列我没有修改,所以值为242没变。
这样就获得了对应的库里,某个表的任何一列的变化的解析。
监听mysql表内容变化 使用canal_2 监听mysql表内容变化,使用canal相关推荐
- mysql cmd 实时监控_mysql实时监听sql语句
[临时配置] 1.首先使用cmd命令行终端连接mysql C:\Users\houxin>mysql -h127.0.0.1 -uroot -p 输入密码,连接成功 2.设置数据库执行的日志文件 ...
- java 持久监听blockqueue的变化_Curator目录监听
Curator目录监听 write by donaldhan, 2018-06-29 09:40 引言 上一篇文章,我们简单看一下Curator的CDRWA相关的构造器,及Curator框架实现,[C ...
- php 如何让html表单当中的数据在修改mysql的时候自动变更_怎么用php把html表单内容写入数据库?...
慕工程0101907 1:首先要使用PHP的超全局变量 $_GET 和 $_POST 用于收集表单数据(form-data)2:然后使用INSERT INTO 语句用于向数据库表中插入新记录.具体示例 ...
- mysql gh 划线,gh-ost:在线DDL修改MySQL表结构工具
在之前,我分享过一次pt-online-schema-change在线DDL的工具实践记录,在实际使用过程中,发现部门的很多老系统大量使用了触发器,从而无法使用这个工具,非常遗憾!导致很多DDL变更都 ...
- 高可用Mysql架构_Mysql主从复制、Mysql双主热备、Mysql双主双从、Mysql读写分离(Mycat中间件)、Mysql分库分表架构(Mycat中间件)的演变...
[Mysql主从复制] 解决的问题 数据分布:比如一共150台机器,分别往电信.网通.移动各放50台,这样无论在哪个网络访问都很快.其次按照地域,比如国内国外,北方南方,这样地域性访问解决了. 负载均 ...
- 不用Oracle?基于MySQL数据库下亿级数据的分库分表
墨墨导读:本文以一个实际的项目应用为例,层层向大家剖析如何进行数据库的优化.项目背景是企业级的统一消息处理平台,客户数据在5千万加,每分钟处理消息流水1千万,每天消息流水1亿左右. 数据库在金融行业怎 ...
- 基于MySQL数据库下亿级数据的分库分表
来自:www.cnblogs.com/jpfss/ 移动互联网时代,海量的用户数据每天都在产生,基于用户使用数据等这样的分析,都需要依靠数据统计和分析,当数据量小时,数据库方面的优化显得不太重要,一旦 ...
- 干掉MySQL!阿里云MVP专家的分库分表设计,搞得太棒了!
孙玄,江湖人称"玄姐",前58集团技术委员会主席,前转转二手交易平台首席架构师.今天想跟你聊点儿企业里那些年薪百万的架构师,他们的架构设计思维是如何升级的,以及他们是如何玩转 My ...
- mysql技术内幕innodb存储引擎——表索引算法和锁_(转)Mysql技术内幕InnoDB存储引擎-表索引算法和锁...
表 原文:http://yingminxing.com/mysql%E6%8A%80%E6%9C%AF%E5%86%85%E5%B9%95innodb%E5%AD%98%E5%82%A8%E5%BC% ...
最新文章
- ASP.NET杂谈-一切都从web.config说起(2)(ConfigSections详解-上 )
- 书评 - 《展望敏捷软件测试》
- Curator实现分布式锁的基本原理-构造函数
- MyEclipse移动开发教程:迁移HTML5移动项目到PhoneGap(二)
- Chapter7-10_Deep Learning for Question Answering (1/2)
- 測试新浪微博@小冰 为代码机器人的一些方法
- L-BFGS算法/Broyden族/BFGS算法/阻尼牛顿法的Python实现代码
- 牛逼了 这 7 个 Python 入门实战项目,我打 99.99 分
- aspen怎么做灵敏度分析_灵敏度分析 aspen
- 【安全资讯】熊猫烧香之后15年,网络变安全了吗?
- 字符串函数---atoi()函数详解及实现(完整版)
- Microsoft Visio 2010 安装失败 安装界面闪退
- Facebook广告投放:WC广告的优点和缺点
- 软件安全实验——lab10(二、TCP/IP攻击实验)
- 重装系统遇上reboot and select proper boot device ...问题解决方案
- 织梦DedeCMS文章列表页自动统计当前栏目文档总数的方法
- 看90后开发的游戏如何闯进AppStore前十
- 桌面显示电脑配置的PE_你还用软件看电脑配置?分享三种无需软件查看配置的方法...
- IT外包行业到底需要什么样的老板?
- PHPCMS本地项目二次开发流程
热门文章
- rda冗余分析步骤_文献综述,步骤与问题!
- python len函数_Python 初学者必备的常用内置函数
- java 多态性 变量_java – 与实例变量的多态性
- html对话框跳转页面,html5各种页面切换效果和模态对话框用法总结
- 怎么查到运行的时间_“我的成考录取通知书怎么还没来,它是不是迷路了?”...
- 湖南工业大学计算机专硕调剂,2020考研调剂:湖南工业大学生物信息实验室2020考研调剂信息...
- php核心语法,PHP核心语法总结
- exp imp 及参数
- java 混淆 js_Vue javascript和css混淆
- 基于JAVA+Servlet+JSP+MYSQL的高校社团管理系统