前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >缓存同步 Canal

缓存同步 Canal

作者头像
收心
发布2022-08-24 16:19:23
1K0
发布2022-08-24 16:19:23
举报
文章被收录于专栏:Java实战博客

缓存同步的常见方式

  • 设置有效期
    • 给缓存社会有效期,到期删除,再来查询,就查数据库,在放入缓存
  • 同步双写
    • 修改DB时,同步修改DB
  • 异步通知
    • 修改DB时,发送事件通知
    • 比如:MQ、Canal

上面场景,只要不傻都知道。各有优势,我就不说了,本文介绍Canal

什么是Canal 需要JDK

Canal主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费

Cnanl地址:https://github.com/alibaba/canal

Canal原理

利用Mysql主从同步机制来实现的。

  • MySQL master 将数据变更写入二进制日志( binary log, 其中记录叫做二进制日志事件binary log events,可以通过 show binlog events 进行查看)
  • MySQL slave 将 master 的 binary log events 拷贝到它的中继日志(relay log)
  • MySQL slave 重放 relay log 中事件,将数据变更反映它自己的数据
canal 工作原理
  • canal 模拟 MySQL slave 的交互协议,伪装自己为 MySQL slave ,向 MySQL master 发送dump 协议
  • MySQL master 收到 dump 请求,开始推送 binary log 给 slave (即 canal )
  • canal 解析 binary log 对象(原始为 byte 流)

Canal 伪装成slave节点,监听master binary log的变化。将此信息发送到Canal客户端中。就完成了异步通知了!

修改Mysql配置

修改mysql配置,配置文件一般就是my.cnf中,不管是啥,只要是mysqld就行了

代码语言:javascript
复制
[mysqld]
# 这是指定服务编号,我怕你重启报错,建议加上吧!
server-id= 1
# 指定binlog日志名称,傻逼mysql有些文件夹不允许随便指定,error.log说了没文件,创建了文件也不行,去他妈的!
log-bin=/var/log/mysql/mysql-bin.log
# 指定mysql的binlog日志记录哪个db
binlog-do-db=hello,mysql
binlog-format=ROW # 选择 ROW 模式复制

重启mysql

代码语言:javascript
复制
systemctl restart mysql复制

确定重启成功了

代码语言:javascript
复制
systemctl restart mysql复制

给Canal创建一个配置用户,用于管理,最好限制操作库的权限 参考:https://cloud.tencent.com/developer/article/1936731

代码语言:javascript
复制
CREATE USER 'canal'@'%' IDENTIFIED BY 'canal';
GRANT all privileges ON *.* TO 'canal'@'%';
-- 如果你root没有系统用户则不可用使用授权命令 添加身份:grant system_user on *.* to 'root';
-- 不知道是不是有啥问题,反正得要配置一下这个
update `mysql`.`user` SET `plugin` ='mysql_native_password' where User = 'canal';
flush privileges;


Drop User 'canal'@'%';
select Host,User from mysql.user;复制

查看主从状态

代码语言:javascript
复制
-- 查看主从状态
SHOW MASTER STATUS;复制

安装Canal

下载:https://github.com/alibaba/canal/releases/tag/canal-1.1.6

建议看官方教程:https://github.com/alibaba/canal/wiki/QuickStart

添加一些配置文件

conf/canal.properties

代码语言:javascript
复制
# tcp bind ip
canal.ip =192.168.31.19复制

example/instance.properties

代码语言:javascript
复制
## mysql serverId , v1.0.26+ will autoGen 这里说了1.0.26 就不用配置了
# canal.instance.mysql.slaveId=0

# position info
canal.instance.master.address=127.0.0.1:3306
# 配置主从在用的binlog文件名 由执行show master status;得到
canal.instance.master.journal.name=mysql-bin.000006
canal.instance.master.position=157
canal.instance.master.timestamp=
canal.instance.master.gtid=

# username/password 我们刚才创建的就是canal,密码也是
canal.instance.dbUsername=canal
canal.instance.dbPassword=canal
canal.instance.connectionCharset = UTF-8复制

我当前是Ubuntu,安装JDK8

代码语言:javascript
复制
apt install openjdk-8-jdk复制

禁用防火墙

代码语言:javascript
复制
systemctl stop firewalld.service


systemctl status firewalld.service 复制

启动Canal

代码语言:javascript
复制
文件需要执行的权限
./startup.sh复制

启动完成后,看一下端口是否被占用

代码语言:javascript
复制
lsof -i:11111复制

如果被占用,说明启动成功!

最好看一下控制台

代码语言:javascript
复制
cat /你的Canal安装路径/logs/canal/canal.log复制

springboot接入 canal

本次使用是这个:https://github.com/NormanGyllenhaal/canal-client 有其他java库,自行寻找其他也可使用!

代码语言:javascript
复制
        <dependency>
            <groupId>top.javatool</groupId>
            <artifactId>canal-spring-boot-starter</artifactId>
            <version>1.2.1-RELEASE</version>
        </dependency>复制

配置文件

代码语言:javascript
复制
# Canal 配置信息
#  多个服务地址以逗号隔开
canal.server=192.168.31.34:11111
#  instance名称
canal.destination=example
# 消费时间间隔,单位秒,默认1
canal.timeout=3复制

监听User表 增、删、改。

代码语言:javascript
复制
import com.zanglikun.springdataredisdemo.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import top.javatool.canal.client.annotation.CanalTable;
import top.javatool.canal.client.handler.EntryHandler;

@Slf4j
@Component
@CanalTable("User") // ① 要监听到表
public class CanalTest implements EntryHandler<User> { // ② 实现接口,指定User,主动重写方法

    @Override
    public void insert(User user) {
        EntryHandler.super.insert(user);
        log.info("插入了数据"+user.toString());
    }

    @Override
    public void update(User before, User after) {
        EntryHandler.super.update(before, after);
        log.info("更新前数据"+before.toString());
        log.info("更新后数据"+after.toString());
    }

    @Override
    public void delete(User user) {
        EntryHandler.super.delete(user);
        System.out.println("执行了");
        log.info("删除了"+user.toString());
    }
}复制

启动即可

日志会打印出变化,我们后期根据User的变化更新相应的缓存数据即可!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 缓存同步的常见方式
  • 什么是Canal 需要JDK
  • Canal原理
    • canal 工作原理
    • 修改Mysql配置
    • 安装Canal
    • springboot接入 canal
    相关产品与服务
    云数据库 MySQL
    腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档