Canal数据同步原理简介及应用

在使用缓存时,不可避免地会遇到数据库同步问题,即当Mysql数据库中的数据更新之后,需要同步更新Redis缓存。一种做法是在更新数据库时删除Redis中的缓存。但是这种方式无疑会将业务逻辑复杂化,稍微不注意就有可能忘记更新缓存,导致数据不一致的问题。因此,另一种较为常见的做法是订阅Mysql的增加、修改和删除操作,当数据库数据发生变动时,自动监听数据的变化,更新缓存。Canal就是做这个事情的。

1. Canal工作原理

canal是应阿里存在杭州和美国的双机房部署,存在跨机房同步的业务需求而提出的。通过对数据库日志的分析,获取增量变更进行数据同步,实现MySQL数据库的增量订阅&消费的业务。快速通道

在这里插入图片描述

canal的工作原理:

  1. canal模拟mysql slave的交互协议,伪装自己为mysql slave,向mysql master发送dump协议;
  2. mysql master收到dump请求,开始推送binary log给slave(canal);
  3. canal解析binary log对象(原始的字节流)

2. Canal安装与配置

2.1 开启binlog模式

canal是基于mysql的主从模式实现的,所以必须先开启binlog。

这里记录一下在docker中安装vim的方法:

apt-get update
apt-get install vim

进入mysql容器,配置/etc/mysql/my.cnf如下:

#binlog config
log-bin=/var/lib/mysql/mysql-bin
server-id=12097   #mysql数据库的唯一标识

2.2 创建测试账号

使用root用户创建用户账号并授予权限

#使用root账号登录
mysql -uroot -p
#输入密码
#创建用户账号canal,密码为canal
create user canal@'%' identified by 'canal';
grant select, replication slave, replication client, super on *.* to 'canal'@'%';
flush privileges;
#退出mysql和mysql容器
exit
#重启mysql容器
docker restart mysql

2.3 canal容器安装

#下载镜像
docker pull docker.io/canal/canal-server
#容器安装
docker run -p 11111:11111 --name canal -d docker.io/canal/canal-server
#登录canal
docker exec -it canal /bin/bash
#配置canal
vi canal.properties
#canal.id = 10039   #这里需要和之前配置的mysql容器的server-id不同
#配置canal实例,同步配置,具体见下图
vi example/instance.properties
#配置完成后退出并重启canal容器
docker restart canal

在这里插入图片描述

3. 搭建Canal微服务

此时,若用户执行数据库操作,binlog将会被canal捕获到,并解析到数据。我们可以将解析出来的数据进行同步到redis中。

下面,我们创建一个独立的程序,并监控canal服务器,获取binlog日志,解析数据,将数据更新到redis中,这样就能保证数据库和缓存中的数据保持一致了。

添加依赖:

        <!-- canal依赖 -->
        <dependency>
            <groupId>com.xpand</groupId>
            <artifactId>starter-canal</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>

application.yml中添加配置:

#canal配置
canal:
  client:
    instances:
      example:
        host: 192.168.137.118
        port: 11111

在Application类上添加注解@EnableCanalClient

监听代码如下:

@CanalEventListener
public class MyEventListener {
 
    @InsertListenPoint
    public void onEvent(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        //do something...
        List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();
        for (CanalEntry.Column column : afterColumnsList) {
            System.out.println(column.getName() + ":" + column.getValue());
        }
    }
 
    @UpdateListenPoint
    public void onEvent1(CanalEntry.RowData rowData) {
        //do something...
    }
 
    @DeleteListenPoint
    public void onEvent3(CanalEntry.EventType eventType) {
        //do something...
    }
 
    @ListenPoint(destination = "example", schema = "canal-test", table = {"t_user", "test_table"}, eventType = CanalEntry.EventType.UPDATE)
    public void onEvent4(CanalEntry.EventType eventType, CanalEntry.RowData rowData) {
        //do something...
    }
}

如图插入数据时,canal微服务可以监听到数据。

在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java8新特性及实战视频教程完整版Java 8 API添加了一个新的抽象称为流Stream,可以让你以一种声明的方式处理数据。Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。使用Lambda 表达式可以使代码变的更加简洁紧凑。Java8实战视频-01让方法参数具备行为能力Java8实战视频-02Lambda表达式初探Java8实战视频-03Lambda语法精讲Java8实战视频-04Lambda使用深入解析Java8实战视频-05Lambda方法推导详细解析-上.wmvJava8实战视频-06Lambda方法推导详细解析-下Java8实战视频-07Stream入门及Stream在JVM中的线程表现Java8实战视频-08Stream知识点总结Stream源码阅读Java8实战视频-09如何创建Stream上集Java8实战视频-10如何创建Stream下集.wmvJava8实战视频-11Stream之filter,distinct,skip,limit,map,flatmap详细介绍Java8实战视频-12Stream之Find,Match,Reduce详细介绍Java8实战视频-13NumericStream的详细介绍以及和Stream之间的相互转换Java8实战视频-14Stream综合练习,熟练掌握API的用法Java8实战视频-15在Optional出现之前经常遇到的空指针异常.wmvJava8实战视频-16Optional的介绍以及API的详解Java8实战视频-17Optional之flatMap,综合练习,Optional源码剖析Java8实战视频-18初识Collector体会Collector的强大Java8实战视频-19Collector使用方法深入详细介绍-01Java8实战视频-20Collector使用方法深入详细介绍-02Java8实战视频-21Collector使用方法深入详细介绍-03.wmvJava8实战视频-22Collector使用方法深入详细介绍-04Java8实战视频-23Collector原理讲解,JDK自带Collector源码深度剖析Java8实战视频-24自定义Collector,结合Stream的使用详细介绍Java8实战视频-25Parallel Stream编程体验,充分利用多核机器加快计算速度Java8实战视频-26Fork Join框架实例深入讲解Java8实战视频-27Spliterator接口源码剖析以及自定义Spliterator实现一个Stream.wmvJava8实战视频-28Default方法的介绍和简单的例子Java8实战视频-29Default方法解决多重继承冲突的三大原则详细介绍Java8实战视频-30多线程Future设计模式原理详细介绍,并且实现一个Future程序Java8实战视频-31JDK自带Future,Callable,ExecutorService介绍Java8实战视频-32实现一个异步基于事件回调的Future程序.wmvJava8实战视频-33CompletableFuture用法入门介绍Java8实战视频-34CompletableFuture之supplyAsync详细介绍Java8实战视频-35CompletableFuture流水线工作,join多个异步任务详细讲解Java8实战视频-36CompletableFuture常用API的重点详解-上Java8实战视频-37CompletableFuture常用API的重点详解-下Java8实战视频-38JDK老DateAPI存在的问题,新的DateAPI之LocalDate用法及其介绍.wmvJava8实战视频-39New Date API之LocalTime,LocalDateTime,Instant,Duration,Period详细介绍Java8实战视频-40New Date API之format和parse介绍

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值