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

如何保证数据库与 Redis 的数据一致性

目录

读场景

写场景

延时双删

先删除 Redis 中的数据,还是先修改数据库

先删除 Redis,再修改数据库

先修改数据库,再删除 Redis

为什么要两次删除 Redis 中的数据

为什么要延时一段时间

需要保证强一致性

分布式锁

共享锁与排他锁

可以有一定的延时

使用 MQ 中间件

使用 Canal 中间件


对于这个问题,分为读场景和写场景。

读场景

客户端发送请求后,会先从 Redis 中获取信息,若获取到,就直接返回;若没有获取到,就会查询数据库,并将查询到的数据写回 Redis 中,从而保证数据库与 Redis 的数据一致性。

写场景

对于写场景,由于数据库中的数据发生了改变,需要将 Redis 中的数据也同步进行改变,这就涉及到了数据的一致性问题。

延时双删

先删除 Redis 中的数据,再修改数据库中的数据,延迟一段时间后再次删除 Redis 中的数据。

对于延时双删,有下面几个问题:

先删除 Redis 中的数据,还是先修改数据库

在下面的情景中,Redis 与数据库中存储的数据均为 10。

先删除 Redis,再修改数据库

第一种情况:

现有两个线程,线程1 先将缓存删除,再将数据库中的数据更新为 20。这时线程2 查询数据,由于此时数据库中的数据还未同步至 Redis 中,那么线程2 在 Redis 中查询不到数据,就会从数据库中查询到 20,并将 20 写回 Redis 中。此时 Redis 与数据库中的数据是一致的。

第二种情况:

当线程1 删除 Redis 中的数据后,线程2 查询数据,但是由于 Redis 中没有数据,就会从数据库中查询到 10,并将 10 写入 Redis 中。但是线程1 将数据库修改为 20,这也就导致了 Redis 与数据库中的数据不一致。

先修改数据库,再删除 Redis

第一种情况:

线程2 将数据库修改为 20,并将 Redis 中的数据删除。此时线程1 查询 Redis 中的数据,由于没有查询到,就会从数据库中获取,由于线程2 已经将数据库修改为 20,于是线程1 就会获取到 20,并将 20 写入 Redis 中,此时数据库与 Redis 中的数据是一致的。

第二种情况:

线程1 先查询缓存信息,由于缓存的信息可能过期,于是就会查询不到,那么就会查询数据库,数据库中的数据为 10。此时线程2 将数据库中的数据更新为 20,并删除 Redis 中的数据,但是线程 1 将10 写入 Redis 中,就导致数据库中的数据与 Redis 不一致。

为什么要两次删除 Redis 中的数据

删除两次 Redis 中的数据后,无论 Redis 中的数据是正确的,还是错误的,都会被删除,那么当下一次查询数据时,由于 Redis 中没有数据,就会将数据库中的新数据同步至 Redis 中,保证了 Redis 与数据库的数据一致性。

为什么要延时一段时间

这是因为数据库也是主从结构的,当主节点修改完数据后,需要一定的时间将数据同步至从节点。若不加以等待,直接将数据同步至 Redis 中,那么此时 Redis 中的数据就有可能是从节点中的旧数据,也就不能保证 Redis 与数据库的数据一致性。

但是在实际开发场景中,一般不会使用延时双闪策略,有两个原因:

  • 可能会出现脏数据
  • 由于不知道数据库主从同步如何结束,就不能把握延时的时间

其实对于写场景来说,有两种情况:

  • 需要保证强一致性
  • 可以有一定的延时

下面针对这两种情况给出不同的策略。

需要保证强一致性

分布式锁

在写数据时加锁,在读数据时也加锁,这就能保证在操作的同时不会被其他线程干预。但是代码性能较低。

共享锁与排他锁

使用 Redisson 实现的读写锁。在读的时候添加共享锁,保证读与读之间不互斥,读写互斥。当更新数据时,添加排他锁,读读、读写都互斥。保证了在写数据的同时,别的线程不能进行读操作,避免了脏数据。

需要注意的是,读方法与写方法需要上同一把锁。

可以有一定的延时

使用 MQ 中间件

当修改完数据库中的数据时,使用 MQ 异步通知删除 Redis 中的数据。

使用 Canal 中间件

不需要更改业务代码,只需部署一个 Canal 服务。Canal 服务把自己伪装成mysql的一个从节点。当数据库更新以后,Canal 会读取 binlog 数据,然后再通过 Canal 的客户端获取到数据,并更新缓存即可。

http://www.dtcms.com/a/605763.html

相关文章:

  • redis连接服务
  • Linux systemd闲谈杂话(第一篇:概述)
  • Spring 核心技术解析【纯干货版】- XII:Spring 数据访问模块 Spring-R2dbc 模块精讲
  • 手机什么网站可以设计楼房关于网站建设的调查问卷
  • 零基础网站建设教学申请自己邮箱域名
  • JVM 内存结构、堆细分、对象生命周期、内存模型全解析
  • 网络安全编程——基于Python实现的SSH通信(Windows执行)
  • WAF防护:应用层安全的核心堡垒
  • 【OpenCV图像处理】图像去噪:cv.fastNlMeansDenoising()
  • 基于AI Agent模板:快速生成 SQL 测试数据
  • 无锡网站建设方案企业计划书
  • 做购票系统网站网站开发推广方案策划书
  • JVM GC 垃圾回收体系完整讲解
  • JVM 内存结构的详细介绍
  • Linux命令-egrep命令(文本搜索工具)
  • 《Flutter全栈开发实战指南:从零到高级》- 14 -网络请求与数据解析
  • 模板网站配置文件seo难不难
  • div2 1052 个人补题笔记
  • 【1.10】基于FPGA的costas环开发4——鉴相器模块开发
  • C语言编译软件 | 如何选择适合自己的编译器
  • 怎么做网站外贸wordpress 本地 域名绑定
  • DSP中断工作原理
  • 【LeetCode】109. 有序链表转换二叉搜索树
  • Verilog 利用伪随机,时序,按键消抖等,实现一个(打地鼠)游戏
  • 【音视频】均衡器(Equalizer)技术详解
  • win11安装mysql社区版数据库
  • 菏泽定制网站建设推广花艺企业网站建设规划
  • 哪些网站可以做推广婚庆公司网站源码
  • LVS负载均衡群集(一) -- NAT模式
  • 【ZeroRnge WebRTC】RFC 8445:ICE 协议规范(中文整理与译注)