mysql使用redis+canal实现缓存一致性

目录

一、开启binlog日志

1.首先查看是否开启了binlog

2、开启binlog日志,并重启mysql服务

二、授权 canal 链接 MySQL 账号具有作为 MySQL slave 的权限

三、下载配置canal

1、下载 canal, 访问 release 页面 , 选择需要的包下载, 如以 1.0.17 版本为例

2、 修改conf\example文件夹下instance.properties配置文件

3、启动canal服务(windows下是bat,linux是sh)

四、基于Canal通知原理

五、项目集成

1、pom依赖

2、编写依赖

3、修改Item实体类

4、编写监听器(Redis/ jvm缓存同步) 

六、测试

1、数据库表数据和redis数据

2、添加数据

3、修改数据

​编辑4、删除数据


一、开启binlog日志

1.首先查看是否开启了binlog

show variables like '%log_bin%';

如果是OFF说明位开启

2、开启binlog日志,并重启mysql服务

右键我的电脑——管理——服务——MYSQL——属性

这里是my.ini地址

在[mysqld]底下添加

log-bin= mysqlbinlog

binlog-format=ROW

在这里插入图片描述

配置好之后,要进行重启mysql服务

查看状态 

show variables like '%log_bin%';

开启成功 

二、授权 canal 链接 MySQL 账号具有作为 MySQL slave 的权限

CREATE USER canal IDENTIFIED BY 'canal';  
GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'canal'@'%';
-- GRANT ALL PRIVILEGES ON *.* TO 'canal'@'%' ;
FLUSH PRIVILEGES;

三、下载配置canal

1、下载 canal, 访问 release 页面 , 选择需要的包下载, 如以 1.0.17 版本为例

解压后

2、 修改conf\example文件夹下instance.properties配置文件

最终配置文件

#################################################

## mysql serverId , v1.0.26+ will autoGen

# canal.instance.mysql.slaveId=0

# enable gtid use true/false

canal.instance.gtidon=false

# 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.master.gtid=

# rds oss binlog

canal.instance.rds.accesskey=

canal.instance.rds.secretkey=

canal.instance.rds.instanceId=

# table meta tsdb info

canal.instance.tsdb.enable=true

#canal.instance.tsdb.url=jdbc:mysql://127.0.0.1:3306/canal_tsdb

#canal.instance.tsdb.dbUsername=canal

#canal.instance.tsdb.dbPassword=canal

#canal.instance.standby.address =

#canal.instance.standby.journal.name =

#canal.instance.standby.position =

#canal.instance.standby.timestamp =

#canal.instance.standby.gtid=

# username/password

canal.instance.dbUsername=root

canal.instance.dbPassword=msir1234

canal.instance.connectionCharset = UTF-8

# enable druid Decrypt database password

canal.instance.enableDruid=false

#canal.instance.pwdPublicKey=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALK4BUxdDltRRE5/zXpVEVPUgunvscYFtEip3pmLlhrWpacX7y7GCMo2/JM6LeHmiiNdH1FWgGCpUfircSwlWKUCAwEAAQ==

# table regex

canal.instance.filter.regex=.*\\..*

# table black regex

canal.instance.filter.black.regex=mysql\\.slave_.*

# table field filter(format: schema1.tableName1:field1/field2,schema2.tableName2:field1/field2)

#canal.instance.filter.field=test1.t_product:id/subject/keywords,test2.t_company:id/name/contact/ch

# table field black filter(format: schema1.tableName1:field1/field2,schema2.tableName2:field1/field2)

#canal.instance.filter.black.field=test1.t_product:subject/product_image,test2.t_company:id/name/contact/ch

# mq config

canal.mq.topic=example

# dynamic topic route by schema or table regex

#canal.mq.dynamicTopic=mytest1.user,topic2:mytest2\\..*,.*\\..*

canal.mq.partition=0

# hash partition config

#canal.mq.enableDynamicQueuePartition=false

#canal.mq.partitionsNum=3

#canal.mq.dynamicTopicPartitionNum=test.*:4,mycanal:6

#canal.mq.partitionHash=test.table:id^name,.*\\..*

#################################################

3、启动canal服务(windows下是bat,linux是sh)

 点击startup.bat启动

查看日志 logs\canal\canal.log,如果启动成功则如下图

四、基于Canal通知原理

在这里插入图片描述

解读:

  • 商品服务完成商品修改后,业务直接结束,没有任何代码侵入
  • Canal监听MySQL数据库的变化,当发现变化后,立即通知缓存服务。
  • 缓存服务接收到canal通知,更新缓存

五、项目集成

1、pom依赖

使用GitHub上的第三方开源的canal-starter客户端。地址:https://github.com/NormanGyllenhaal/canal-client

<dependency>
        <groupId>top.javatool</groupId>
        <artifactId>canal-spring-boot-starter</artifactId>
        <version>1.2.1-RELEASE</version>
</dependency>

2、编写依赖

canal:
   destination: example
   server: localhost:11111        #canal的ip地址和端口

3、修改Item实体类

Canal推送给canal-client的是被修改的这一行数据(row),而我们引入的canal-client则会帮我们把行数据封装到Item实体类中。这个过程需要知道数据库与实体的映射关系。需要用到JPA的注解:

通过@Id、@Column等注解完成Item与数据库表字段的映射:

注意,如果和数据库名称不同必须用@Column

package com.springboot3.domain;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Id;

/**
 * 
 * @TableName course
 */
@TableName(value ="course")
@Data
public class Course implements Serializable {
    /**
     * 
     */
    @Id
    @TableId
    private String id;

    /**
     * 
     */
    private String name;

    /**
     * 
     */
    @Column(name = "teacher_id")
    private String teacherId;

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;
}

4、编写监听器(Redis/ jvm缓存同步) 

通过实现EntryHandler<T>接口编写监听器,监听Canal消息。注意两点:

  • 实现类通过@CanalTable("course")指定监听的表信息。
  • EntryHandler的泛型是与表对应的实体类
package com.springboot3.handler;

import com.springboot3.domain.Course;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import top.javatool.canal.client.annotation.CanalTable;
import top.javatool.canal.client.handler.EntryHandler;

@CanalTable(value = "Course")
@Component
@Slf4j
public class CourseHandler implements EntryHandler<Course> {
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public void insert(Course course) {
        log.info("insert message  {}", course);
        redisTemplate.opsForValue().set(course.getId(),course);
    }

    @Override
    public void update(Course before, Course after) {
        log.info("update before {} ", before);
        log.info("update after {}", after);
        redisTemplate.opsForValue().set(after.getId(),after);

    }

    @Override
    public void delete(Course course) {
        log.info("delete  {}", course);
        redisTemplate.delete(course.getId());

    }
}

六、测试

1、数据库表数据和redis数据

数据库:

redis:

2、添加数据

添加数据物理

控制台显示:

redis数据库:

3、修改数据

将物理修改为化学

控制台显示:

redis数据库:

4、删除数据

删除化学科目

控制台数据

 redis数据库数据:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/79200.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

无脑入门pytorch系列(四)—— scatter_

本系列教程适用于没有任何pytorch的同学&#xff08;简单的python语法还是要的&#xff09;&#xff0c;从代码的表层出发挖掘代码的深层含义&#xff0c;理解具体的意思和内涵。pytorch的很多函数看着非常简单&#xff0c;但是其中包含了很多内容&#xff0c;不了解其中的意思…

一、window配置微软商店中的Ubuntu,及错误解决方法

&#xff08;1&#xff09;首先&#xff0c;在微软商店中搜索“Ubuntu”&#xff0c;下载你喜欢的版本(此处) &#xff08;2&#xff09;设置适用于window的Linux子系统&#xff0c;跟着红色方框走 点击“确定”之后&#xff0c;会提示你重启电脑&#xff0c;按要求重启电脑即可…

unity中导入自定义模型

unity中导入自定义模型 准备软件步骤1从SoildWorks中导出模型为STEP格式2将STEP格式文件导入到3DS Max中&#xff0c;再导出为FBX格式3将FBX格式导入至unity中 准备软件 需要SoildWorks、3DS Max和Unity 3D软件步骤 1从SoildWorks中导出模型为STEP格式 2将STEP格式文件导入到…

Java Persistence APl(JPA)——JPA是啥? SpringBoot整合JPA JPA的增删改查 条件模糊查询 多对一查询

目录 引出Jpa是啥&#xff1f;Jpa的使用创建实体类写dao接口类写服务类 crud增删改查增加修改根据id删除全查询分页查询 条件查询模糊查询单条件查询多条件查询模糊查询排序查询 多对一查询定义实体类auto主键策略下新增进行全查询测试 全部代码application.yml配置类pom配置文…

K8S核心组件etcd详解(上)

1 介绍 https://etcd.io/docs/v3.5/ etcd是一个高可用的分布式键值存储系统&#xff0c;是CoreOS&#xff08;现在隶属于Red Hat&#xff09;公司开发的一个开源项目。它提供了一个简单的接口来存储和检索键值对数据&#xff0c;并使用Raft协议实现了分布式一致性。etcd广泛应用…

国产化系统中遇到的视频花屏、卡顿以及延迟问题的记录与总结

目录 1、国产化系统概述 1.1、国产化操作系统与国产化CPU 1.2、国产化服务器操作系统 1.3、当前国产化系统的主流配置 2、视频解码花屏与卡顿问题 2.1、视频解码花屏 2.2、视频解码卡顿 2.3、关于I帧和P帧的说明 3、国产显卡处理速度慢导致图像卡顿问题 3.1、视频延…

【Android Framework (十二) 】- 智能硬件设备开发

文章目录 前言智能硬件的定义与应用智能硬件产品开发流程智能硬件开发所涉及的技术体系概述关于主板选型主板CPU芯片的选择关于串口通信 总结 前言 针对我过往工作经历&#xff0c;曾在一家智能科技任职Android开发工程师&#xff0c;简单介绍下关于任职期间接触和开发过的一些…

后端返回图片资源错误404,前端使用默认图片

后端返回的图片资源可能会因为各种原因&#xff08;后台误删&#xff0c;地址更改未及时更新&#xff0c;损毁&#xff09;出现无法展示的情况&#xff0c;比如这种报错 就会导致图片资源错误&#xff0c;页面出现这种情况 用户体验很不好&#xff0c;为了改善这种情况&#xf…

第6章:支持向量机

间隔与支持向量 w为法向量&#xff0c;决定的是超平面的方向。b是偏移项&#xff0c;决定了超平面与原点之间的距离。 为什么最大化间隔&#xff0c;得到的就是最优平面呢&#xff1f; 当超平面没有正确划分正负样本时&#xff0c;几何间隔为负数。几何间隔&#xff0c;各个…

chatglm llm实时流api接口及post访问

参考&#xff1a; https://github.com/THUDM/ChatGLM-6B/pull/573/commits/02947052eefe392fd9f9632894e9551a805c6109 https://github.com/THUDM/ChatGLM-6B/pull/573 1、代码&#xff1a; 提前安装&#xff1a; sse_starlette、fastapi python stream_api.pystream_api.p…

ssm社区管理与服务系统源码和论文

ssm社区管理与服务的设计与实现031 开发工具&#xff1a;idea 数据库mysql5.7 数据库链接工具&#xff1a;navcat,小海豚等 技术&#xff1a;ssm 研究背景 当今时代是飞速发展的信息时代。在各行各业中离不开信息处理&#xff0c;这正是计算机被广泛应用于信息管理系统的…

安装和配置 Ansible

安装和配置 Ansible 按照下方所述&#xff0c;在控制节点 control.area12.example.com 上安装和配置 Ansible&#xff1a; 安装所需的软件包 创建名为 /home/curtis/ansible/inventory 的静态清单文件&#xff0c;以满足以下要求&#xff1a; node1 是 dev 主机组的成员 node2 …

MYSQL 作业三

创建一个student表格&#xff1a; create table student( id int(10) not null unique primary key, name varchar(20) not null, sex varchar(4), birth year, department varchar(20), address varchar(50) ); 创建一个score表格 create table score( id int(10) n…

开发测试框架一 - 创建springboot工程及基础操作

一、创建及运行方式 1. 从官网导入&#xff1a; 注意&#xff1a;由于我的java版本是1.8&#xff1b;所以选中了spring2.7.14&#xff1b;如果你的java版本是9及以上&#xff0c;选中spring3相关的同时Java 版本也要对应起来 2. 创建第一个get请求 创建Controller package及…

opencv实战项目 手势识别-手势控制鼠标

手势识别系列文章目录 手势识别是一种人机交互技术&#xff0c;通过识别人的手势动作&#xff0c;从而实现对计算机、智能手机、智能电视等设备的操作和控制。 1. opencv实现手部追踪&#xff08;定位手部关键点&#xff09; 2.opencv实战项目 实现手势跟踪并返回位置信息&…

2019年9月全国计算机等级考试真题(C语言二级)

2019年9月全国计算机等级考试真题&#xff08;C语言二级&#xff09; 第1题 1、“商品”与“顾客”两个实体集之间的联系一般是 A. 一对一 B. 一对多 C. 多对一 D. 多对多 正确答案&#xff1a;D 第2题 定义学生选修课程的关系模式&#xff1a;SC&#xff08;S#&#xff0c…

.netcore grpc双向流方法详解

一、双向流处理概述 简单来讲客户端可以向服务端发送消息流&#xff0c;服务端也可以向客户端传输响应流&#xff0c;即客户端和服务端可以互相通讯客户端无需发送消息即可开始双向流式处理调用 。 客户端可选择使用 RequestStream.WriteAsync 发送消息。 使用 ResponseStream…

Golang 基础语法问答

使用值为 nil 的 slice、map 会发生什么&#xff1f; 允许对值为 nil 的 slice 添加元素&#xff0c;但是对值为 nil 的 map 添加元素时会造成运行时 panic。 // map错误示例 func main() {var m map[string]intm["one"] 1 // error: panic: assignment to entry …

(5)所有角色数据分析页面的构建-5

所有角色数据分析页面&#xff0c;包括一个时间轴柱状图、六个散点图、六个柱状图(每个属性角色的生命值/防御力/攻击力的max与min的对比)。 """绘图""" from pyecharts.charts import Timeline from find_type import FindType import pandas …

特殊链表(循环单链表,循环双链表,静态链表)

目录 1.循环单链表的初始化 2.循环双链表 3. 静态链表 (1)静态链表的初始化 (2)静态链表的插入 1.循环单链表的初始化 typedef int ElemType; typedef struct LNode{ElemType data;struct LNode *next;}LNode,*LinkList;bool InitList(LinkList &L) {L(LNode*)malloc(…