首先要Canal服务端下载:链接: https://pan.baidu.com/s/1FwEnqPC1mwNXKRwJuMiLdg 密码: r8xf

连接数据库的时候需要给予连接数据库权限:在my.ini配置文件里加上 log-bin=mysql-bin 这个就行了

连接数据库的账号需要授权

CREATE USER cqlpz IDENTIFIED BY 'cqlpz';

GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'cqlpz'@'%';

FLUSH PRIVILEGES; 创建一个账号并给予权限

解压出来有4个目录

2.conf 里面canal.properties 配置canal自己的 比如多个服务连接,canal缓存名称

这是example里面的内容;

两个properties就是配置自己的数据库连接,meta.dat相当于启动canal服务过后的额缓存信息

3.lib 就是canal需要的jar

4.logs 日志文件

maven引入jar

 1 <dependency>
2 <groupId>com.alibaba.otter</groupId>
3 <artifactId>canal.client</artifactId>
4 <version>1.0.25</version>
5 </dependency>
6 <dependency>
7 <groupId>redis.clients</groupId>
8 <artifactId>jedis</artifactId>
9 <version>2.9.0</version>
10 </dependency>

java代码

1.连接canal服务

 // 创建链接
CanalConnector connector = CanalConnectors.newSingleConnector(
new InetSocketAddress(AddressUtils.getHostIp(), 端口),
"canal名称(虚拟数据名)",
"数据库账号",
"数据库密码");

2.连接某个数据库

connector.connect();
connector.subscribe("监控的数据库\\..*");
connector.rollback();

3.获取操作的事件

Message message = connector.getWithoutAck(数量); // 获取指定数量的数据
List<Entry> entrys=message.getEntries();
for (Entry entry : entrys) {
if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN ||entry.getEntryType() == EntryType.TRANSACTIONEND) {
continue;
}
RowChange rowChage = null;
try {
rowChage = RowChange.parseFrom(entry.getStoreValue());
} catch (InvalidProtocolBufferException e) {
System.out.println("获取数据失败:"+e.getMessage());
}
EventType eventType = rowChage.getEventType();
for (RowData rowData : rowChage.getRowDatasList()) {
if (eventType.equals(EventType.DELETE)) {
rowData.getBeforeColumnsList();//删除的所有数据
} else if (eventType.equals(EventType.INSERT)) {
rowData.getAfterColumnsList();//添加的所有数据
}else if(eventType.equals(EventType.UPDATE)) {
rowData.getAfterColumnsList();//修改的所有数据
}
}

完整的java类

public class ClientSample {
private static Logger logger = LoggerFactory.getLogger(ClientSample.class); public void startCanalThread(){
Thread thread = new StartCanalThread();
thread.start();
}
/**
* canal 线程
*/
public class StartCanalThread extends Thread {
@Override
public void run() {
// 创建链接
CanalConnector connector = CanalConnectors.newSingleConnector(new InetSocketAddress("localhost", 11111),
"longpizi",
"longpizi",
"cqlongpizi");
connector.connect();
connector.subscribe("test\\..*");
connector.rollback();
try {
while (true) {
// 获取指定数量的数据
Message message = connector.getWithoutAck(1000);
long batchId = message.getId();
if (batchId != -1 && message.getEntries().size() > 0) {
printEntry(message.getEntries());
}
connector.ack(batchId); // 提交确认
Thread.sleep(2000);
} }catch (Exception e){
logger.error("Canal线程异常,已终止:"+e.getMessage());
} finally {
//中断Canal连接
connector.disconnect();
}
}
} /**
* 数据库执行的操作
* @param entrys
*/
private static void printEntry( List<Entry> entrys) {
for (Entry entry : entrys) {
//操作事物 忽略
if (entry.getEntryType() == EntryType.TRANSACTIONBEGIN || entry.getEntryType() == EntryType.TRANSACTIONEND) { continue; }
RowChange rowChage = null;//执行事件信息
String database=null;//执行的数据库
String table=null;//执行的表
try {
database=entry.getHeader().getSchemaName();
table=entry.getHeader().getTableName();
rowChage = RowChange.parseFrom(entry.getStoreValue());
} catch (InvalidProtocolBufferException e) {
logger.error("获取数据失败:"+e.getMessage());
}
//获取执行的事件
EventType eventType = rowChage.getEventType();
for (RowData rowData : rowChage.getRowDatasList()) {
//删除操作
if (eventType.equals(EventType.DELETE)) {
redisDelete(rowData.getBeforeColumnsList(),database,table);
}
//添加操作
else if (eventType.equals(EventType.INSERT)) {
redisInsert(rowData.getAfterColumnsList(),database,table);
}
//修改操作
else if(eventType.equals(EventType.UPDATE)) {
redisUpdate(rowData.getAfterColumnsList(),database,table);
}
//修改表结构
else if(eventType.equals(EventType.ALTER)){
logger.info("修改表结构");
}
}
}
} /**
* 数据库执行了添加操作
* @param columns
* @param database
* @param table
*/
private static void redisInsert( List<Column> columns,String database,String table){
JSONObject json=new JSONObject();
for (Column column : columns) {
json.put(column.getName(), column.getValue());
}
System.out.println("数据库:"+database+"==>表:"+table+"==>添加数据:"+JSON.toJSONString(json));
} /**
* 数据库执行了修改操作
* @param columns
* @param database
* @param table
*/
private static void redisUpdate( List<Column> columns,String database,String table){
JSONObject json=new JSONObject();
for (Column column : columns) {
json.put(column.getName(), column.getValue());
}
System.out.println("数据库:"+database+"==>表:"+table+"==>修改数据:"+JSON.toJSONString(json));
} /**
* 数据库执行了删除操作
* @param columns
* @param database
* @param table
*/
private static void redisDelete( List<Column> columns,String database,String table){
JSONObject json=new JSONObject();
for (Column column : columns) {
json.put(column.getName(), column.getValue());
}
System.out.println("数据库:"+database+"==>表:"+table+"==>删除数据:"+JSON.toJSONString(json));
}
}

这样就可把操作的数据更新到redis里面了

Canal监控Mysql同步到Redis(菜鸟也能搭建)的更多相关文章

  1. mysql同步之otter/canal环境搭建完整详细版

    接上一篇mysql 5.7多源复制(用于生产库多主库合并到一个查询从库). 这一篇详细介绍otter/canal环境搭建以及当同步出现异常时如何排查.本文主要参考https://blog.csdn.n ...

  2. Zabbix监控mysql配置及故障告警配置

    本文主要介绍zabbix监控mysql的配置,包含使用zabbix自带模板监控mysql相关信息及自定义key监控mysql同步情况.同时介绍了触发器的创建及zabbix通过邮件方式告警配置. 一.配 ...

  3. Canal 实战 | 第一篇:SpringBoot 整合 Canal + RabbitMQ 实现监听 MySQL 数据库同步更新 Redis 缓存

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

  4. canal整合springboot实现mysql数据实时同步到redis

    业务场景: 项目里需要频繁的查询mysql导致mysql的压力太大,此时考虑从内存型数据库redis里查询,但是管理平台里会较为频繁的修改增加mysql里的数据 问题来了: 如何才能保证mysql的数 ...

  5. 转载:阿里canal实现mysql binlog日志解析同步redis

    from: http://www.cnblogs.com/duanxz/p/5062833.html 背景 早期,阿里巴巴B2B公司因为存在杭州和美国双机房部署,存在跨机房同步的业务需求.不过早期的数 ...

  6. Docker安装canal、mysql进行简单测试与实现redis和mysql缓存一致性

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

  7. 【菜鸟玩Linux开发】通过MySQL自动同步刷新Redis

    在服务端开发过程中,一般会使用MySQL等关系型数据库作为最终的存储引擎,Redis其实也可以作为一种键值对型的数据库,但在一些实际场景中,特别是关系型结构并不适合使用Redis直接作为数据库.这俩家 ...

  8. zabbix3.0.4监控mysql主从同步

    zabbix3.0.4监控mysql主从同步 1.监控mysql主从同步原理: 执行一个命令 mysql -u zabbix -pzabbix -e 'show slave status\G' 我们在 ...

  9. 监控mysql主从同步状态脚本

    监控mysql主从同步状态脚本 示例一: cat check_mysql_health #!/bin/sh slave_is=($(mysql -S /tmp/mysql3307.sock -uroo ...

随机推荐

  1. maven项目从本地向本地仓库导入jar包

    方法一(推荐): <dependency> <groupId>guagua-commons</groupId> <artifactId>guagua-c ...

  2. pip速度慢解决办法

    pip速度慢解决办法 sudo pip3 config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 注意加不加sudo是 ...

  3. css实现高度自适应

    要求.上部固定高度50px,下部分自适应剩下整个屏幕 html, body { height: 100%; margin: 0px; padding: 0px; } #main { backgroun ...

  4. frp内网穿透,centos7+frp成功样例

    准备工作: 阿里云服务器一台,备案域名一个,本地服务器一台(本人用的虚拟机centos7) frp文件:frp_0.22.0_linux_amd64.tar.gz 链接:https://pan.bai ...

  5. Python笔记_第四篇_高阶编程_进程、线程、协程_2.线程

    1. 线程概述: 在一个进程的内部,要同时干多件事情,就需要同时运行“多个子任务”,我们把进程内的这些“子任务”叫做线程.也就说线程是进程成的子任务. 线程通常叫做情景的进程.线程是通过向内侧控件的并 ...

  6. Python笔记_第四篇_高阶编程_正则表达式_2.正则表达式入门

    1. 匹配单个字符和数字: . --->> 匹配除换行符以外的任意字符.[0123456789] --->> []字符集合,表示匹配方括号中所包含的任意一个字符.[Thomas ...

  7. 后端Springboot前端VUE实现Excel导入功能

    功能描述:做的是物联网的项目,Excel导入实现的功能是将Excel中的数据批量的导入AEP系统,再导入我们系统中.目前已经完成该功能,前端还会添加进度条优化.对于导入导出功能,推荐这个Git:htt ...

  8. 微信请求参数生成SHA1签名

    package com.dhht.wechat.util; import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObjec ...

  9. Properties in Algebra

    附录-Properties in Algebra 部分证明转载自标注,仅作个人整理查阅用. 范数 (norm) \(^{[1]}\) 要更好的理解范数,就要从函数.几何与矩阵的角度去理解,我尽量讲的通 ...

  10. python中的变量对象小结2

    # .变量名和数据内容是分开存储的. # .数据保存在内存中的一个位置(地址). # .变量中保存着数据在内存中的地址. # 引用就是变量中记录数据的地址. #不可变变量,重新赋值时会重新开辟一个地址 ...