当前位置: 首页 > news >正文

Redis作为缓存,mysql的数据如何与redis进行同步?

Redis作为缓存,mysql的数据如何与redis进行同步?

一定要设置前提,先介绍业务背景

延时双删

  • 双写一致性:当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致
    • 读操作:缓存命中,直接返回;缓存未命中查询数据库,写入缓存,设定超时时间
    • 写操作:延时双删
      • 在这里插入图片描述

问题来了,那么先删除数据库,还是先删除缓存呢?我们都分析一下,这里只分析异常情况

  • 先删除缓存,再删除数据库。假设我们有缓存数据A=10,和数据库数据A=10

    • 线程1先删除缓存
    • 此时线程2查询缓存,未命中,查询数据库A=10,然后写入缓存
    • 线程1然后更新数据库A=20
    • 此时数据不一致了缓存A=10,数据库A=20
      • 在这里插入图片描述
  • 先操作数据库,再删除缓存,假设我们有缓存数据已经过期,和数据库数据A=10

    • 线程1先查询缓存,此时因为我们假设的缓存数据已经过期,查询数据库A=10,还没来得及写入缓存
    • 线程2更新数据库,A=20,然后删除缓存(此时没有缓存,删不删没关系)
    • 线程1写入缓存
    • 此时数据不一致了,缓存A=10,数据库A=20
      • 在这里插入图片描述

我们发现这两种都会导致脏数据的出现,所以,删除两次缓存就出现了。这就是延时双删:删除缓存-修改数据库-延迟一会删除缓存,就是为了降低脏数据的出现,那为什么要延时呢?因为一般情况下,数据库是主从模式,我们要延时一会,让数据库主节点同步到从节点,再删除缓存。但是也会有小问题,因为延时的时间不好把控。所以做不到绝对的强一致。

分布式锁

那有更好的办法吗?我们可以使用分布式锁来解决这个问题

在这里插入图片描述

但是这个显然效率有点太低了,我们可以优化一下

一般缓存数据都是读多写少,我们可以使用读写锁控制

  • 共享锁:读锁readLock,加锁之后,其他线程可以共享读操作排他锁
  • 独占锁writeLock也叫,加锁之后,阻塞其他线程读写操作

这样性能就得到了提升,虽然实现了强一致,但是性能还是有点低

异步通知保证数据最终一致

在这里插入图片描述

最终一致性的保证,主要取决于MQ的可靠性

基于Canal的异步通知

在这里插入图片描述

canal是阿里开发的中间件,主要是基于mysql的主从同步实现的

二进制日志(BNLOG)记录了所有的DDL (数据定义语言)语句和DML(数据操纵语言)语句,但不包括数据查询(SELECT、SHOW)语句。

优点:无代码侵入

总结

  • 允许延时一致的业务,采用异步通知
    • 使用MQ中间中间件,更新数据之后,通知缓存删除
    • 利用canal中间件,不需要修改业务代码,伪装为mysql的一个从节点,canal通过读取binlog数据更新缓
  • 存强一致性的,采用Redisson提供的读写锁
    • 共享锁:读锁readLock,加锁之后,其他线程可以共享读操作排他锁
  • 存强一致性的,采用Redisson提供的读写锁
    • 共享锁:读锁readLock,加锁之后,其他线程可以共享读操作排他锁
    • 独占锁writeLock也叫,加锁之后,阻塞其他线程读写操作
http://www.lryc.cn/news/186680.html

相关文章:

  • 申请免费 SSL 证书为您的小程序加密通信
  • Go 并发编程
  • 鱼眼相机去畸变(图像拉直/展开/矫正)算法及实战总结
  • es6 数据类型
  • 【postgresql】
  • 【C++】空间配置器 allocator:原理及底层解析
  • 微信小程序 movable-area 区域拖动动态组件演示
  • 隔离上网,安全上网
  • NOSQL Redis 数据持久化 RDB、AOF(二) 恢复
  • UDP通信
  • Bootstrap对溢出内容的两种处理:滚动条和隐藏两种方式
  • elasticsearch基本语法
  • Maven Spring jar包启动报错 排查
  • LeetCode-2485-找出中枢整数
  • nano pi m1配置脚本(全志H3)
  • linux--gdb的使用
  • JVM命令行监控工具
  • 系统架构设计:4 论微服务架构及其应用
  • 【C++设计模式之建造者模式:创建型】分析及示例
  • C++day03(动态内存、类中特殊成员函数)
  • 【Leetcode】179. 最大数
  • ArduPilot开源飞控之AP_Baro_MSP
  • openGauss学习笔记-94 openGauss 数据库管理-访问外部数据库-mysql_fdw
  • UML图 - 类图(Class Diagram)
  • sheng的学习笔记-【中文】【吴恩达课后测验】Course 2 - 改善深层神经网络 - 第二周测验
  • Nacos 监控手册
  • 项目需求分析5大常见问题及解决方案
  • C#学习系列相关之多线程(四)----async和await的用法
  • 极智AI | 大模型优化之KV Cache
  • Android 使用 registerForActivityResult() 打开系统相册或相机获取图像