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

数据库和缓存如何保证一致性?

目录

  • 数据库和缓存如何保证一致性?
    • 背景
    • 方案
    • 先更新数据库,还是先更新缓存?
      • 先更新数据库,再更新缓存
      • 先更新缓存,再更新数据库
    • 先更新数据库,还是先删除缓存?
      • 先删除缓存,再更新数据库
      • 先更新数据库,再删除缓存
      • 最终解决方案
        • 总结
          • 先更新数据库再更新缓存
          • 先更新数据库再删除缓存

背景

公司项目是教育方面的产品,对于课程数据使用比较频繁,用户使用的是时候对其响应速度要求较高,随着使用人数越来越多,并发越来越高,查询数据库的频率越来越高,导致接口访问速度越来越差,数据库性能达到瓶颈。

方案

目前解决此类常用数据的方案就是使用缓存,将查看的课程数据缓存到缓存中,这样,在客户端请求数据时,如果能在缓存中命中数据,那就查询缓存,不用在去查询数据库,从而减轻数据库的压力,提高服务器的性能。但是需要注意的是,当数据发生变化的时候,缓存数据也需要同事变更,需要考虑数据库和缓存如何保证一致性?

先更新数据库,还是先更新缓存?

我们首选要考虑的问题,就是如果数据更新的时候,是先更新数据库还是先更新缓存呢?

在这里插入图片描述

先更新数据库,再更新缓存

在这里插入图片描述

这个是属于一个理想状态想的操作,我们想象一下如果并发的情况下一定会出现缓存的数据与数据库的数据不一致的问题,举例说明一下:

  1. A请求和B请求同事更新同一个资源,A想更新这个资源的名称为lesson1,B想更新这个资源的名称为lesson2

  2. 假设A进行更新数据库,已经更新成功了讲数据库的资源名称更新成了lesson1

  3. 在更新缓存之前,B这个请求先进来更新数据库操作,将资源名称更新为lesson2 了,并且同事更新缓存为lesson2

  4. 这个时候A请求才处理更新缓存操作,将缓存更新为lesson1

  5. 这个时候数据库的资源名称为:lesson2,而缓存为lesson1

下面我们画个时序图帮助理解:

在这里插入图片描述

先更新缓存,再更新数据库

其实是一样的道理,并发情况下也一样,只是跟上面的反过来,所以这里就不做赘述了。

先更新数据库,还是先删除缓存?

我们换个思路看看,如果我们不去做更新,而直接删除缓存的,用户更新数据库以后直接删除缓存,这样用户查询的时候查不到缓存就直接取数据库,然后再缓存。其实这个跟上面的类似,只是这种情况在于删除缓存比更新缓存要快的多,出现并发的情况的概率会小很多,而且如果加上缓存失效时间,就更可靠了,下面继续分析。

在这里插入图片描述

先删除缓存,再更新数据库

在这里插入图片描述

  1. 还是A、B两个请求并发,A请求是需要更新数据库资源,B请求则是查询数据库资源
  2. 由于方案是先删除缓存再更新数据库,A请求先删除缓存的数据,缓存删除成功以后,需要更新数据库,再这个时候,B请求进来查询这条数据,先查询缓存,未命中,于是从数据库进行查询,查到的数据为lesson2,并更新缓存数据为lesson2
  3. A删除完缓存以后,再进行更新数据为lesson1值数据库中。
  4. 此时缓存的数据为lesson2,数据库的数据为lesson1

先更新数据库,再删除缓存

在这里插入图片描述

  1. A、B两个请求并发,A请求是需要更新数据库资源,B请求则是查询数据库资源
  2. A先更新数据库为lesson1,更新成功以后,删除缓存;B请求来查询数据 ,查不到,则查询数据库,查到数据,再更新缓存为lesson1
  3. 看起来没问题,但是如果缓存删除的时候,由于网络原因,或者某种不可控的原因删除失败了,那B拿到数据的就是旧的缓存数据,同时也会存在缓存问题与数据库不一致的问题

最终解决方案

总结

如果对缓存命中率要求较高的话就得采用更新数据库再更新缓存的方案,如果对命令率要求不高则采用先更新数据库再删除缓存。前面也分析了这两种方案都有缺陷,都可能在并发情况下存在缓存与数据库不一致。那么针对这两种情况做下优化。

先更新数据库再更新缓存

这种方案前面我们也分析过,在两个更新请求并发执行的时候,会出现数据不一致的问题,因为更新数据库和更新缓存这两个操作是独立的,而我们又没有对操作做任何并发控制,那么当两个线程并发更新它们的话,就会因为写入顺序的不同造成数据的不一致。

这个地方我们可以在更新缓存的时候增加一个分布式锁,保证同一时间只运行一个请求更新缓存,就会不会产生并发问题了,当然引入了锁后,对于写入的性能就会带来影响。然后在此基础上给缓存添加一个过期时间,这样就算出现缓存数据库不一致的情况,也有补偿机制。

先更新数据库再删除缓存

其实这种情况最好解决,我们只需要在删除缓存的时候增加重试机制,引入mq消息,如果删除失败,则进行重试,删除成功,消息消费完成,然后再对缓存增加过期时间作为补偿机制,这样就可以高枕无忧了。

这里也说明一下为什么推荐删除缓存,因为大家知道更新缓存的话,如果这个缓存的数据关联比较多,那么这个查询就会很多,就会很麻烦,如果删除缓存的,就方便多了,速度也会快很多,当然这样缓存命中率就会低很多。

存的数据关联比较多,那么这个查询就会很多,就会很麻烦,如果删除缓存的,就方便多了,速度也会快很多,当然这样缓存命中率就会低很多。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安装 PyQt5 保姆级教程

作者:billy 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 前言 博主之前做应用层开发用的一直是 Qt,这次尝试一下在 python 中使用 Pyqt5 模块来开发 UI 界面,这里做一些…

certum的ip证书购买流程

Certum是成立于欧洲的CA认证机构,经过二十几年的发展Certum已经成为欧洲知名的CA认证机构之一,拥有广泛的客户群体和合作伙伴。IP证书是Certum为只有公网IP地址的网站准备的数字加密服务。今天就随SSL盾小编了解购买Certum旗下的IP证书流程。 第一步&am…

WPF Grid

Resource 在 WPF 中,“Grid” 是一种用于布局的面板控件,而 “Resource” 是一种用于定义可重用对象的机制。您可以将资源定义为 Grid 控件的一部分,以便在整个应用程序中共享和重用。 使用资源可以帮助您简化界面的创建和维护。在 Grid 控件…

总结一些好用的函数

1. <string.h>/<cstring>头文件 中的 memset函数 作用&#xff1a;用于将一段内存区域设置为特定的值(它作用的基本单位是字节) 可以对变量&#xff0c;数组&#xff08;一维数组和二维数组&#xff09;&#xff0c;结构体进行初始化&#xff0c;但是不能对vecto…

数据库进阶教学——读写分离(Mycat1.6+Ubuntu22.04主+Win10从)

目录 1、概述 2、环境准备 3、读写分离实验 3.1、安装jdk 3.2、安装Mycat 3.3、配置Mycat 3.3.1、配置schema.xml ​​​​3.3.2、配置server.xml 3.4、修改主从机远程登陆权限 3.4.1、主机 3.4.2、从机 3.5、启动Mycat 3.6、登录Mycat 3.7、验证 1、概述 读写分…

如何合理配置云服务器的CPU和内存?

​  提到云服务器性能&#xff0c;大抵有两个主要影响因素&#xff0c;CPU 核心数量和内存容量 &#xff0c;它们决定了云服务器的速度和可靠性。日常运用中&#xff0c;我们如何判断网站需要需要更多或更少?如何扩大或缩小它们以优化网站的性能? 一般来说&#xff0c;您拥…

视频遥测终端机的设计需求

目录 1.目的 2.参考文件 3.总体描述 4.硬件资源描述 4.1微控制单元 4.2视频处理单元 4.3性能指标 5.功能要求 5.1系统参数要求 5.1.1系统管理 5.1.2系统配置 5.1.2.1一般参数 5.1.2.2编码参数 5.1.2.3网络参数 5.1.2.4网络服务 5.1.2.5OSD参数 5.1.2.6抓拍 5.…

java设计模式学习之【访问者模式】

文章目录 引言访问者模式简介定义与用途实现方式 使用场景优势与劣势在Spring框架中的应用电脑示例代码地址 引言 设想你是一个艺术馆的管理员&#xff0c;艺术馆里有各种各样的艺术品。每当有游客来访时&#xff0c;根据他们的兴趣&#xff0c;他们可能只想看画、雕塑或特定的…

【开源】基于Vue+SpringBoot的房屋出售出租系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 房屋销售模块2.2 房屋出租模块2.3 预定意向模块2.4 交易订单模块 三、系统展示四、核心代码4.1 查询房屋求租单4.2 查询卖家的房屋求购单4.3 出租意向预定4.4 出租单支付4.5 查询买家房屋销售交易单 五、免责说明 一、摘…

华为云服务器重启后无法连接故障解决

华为云服务器系统为麒麟银河V10sp1&#xff0c;升级sp1.1后继续升级sp2. 升级后重启发现无法连接服务器了。 登录华为云控制台&#xff0c;使用用vnc方式连接成功。 推测应该是网络问题。使用ip addr命令检查&#xff0c;发现网卡eth0处于down状态。 使用命令启动网卡&…

spring security oauth2搭建认证服务器

如图&#xff08;上面图片的代码在业务项目中&#xff09;&#xff0c;第一步在独立的业务项目中&#xff0c;先获取授权码&#xff08;也叫jsessionId&#xff09;、获取授权码的路径就是 /oauth2/authorize&#xff0c;这个路径是oauth2的框架中被OAuth2AuthorizationEndpoin…

如何从RTP包的AP类型包,获取h265的PPS、SPS、VPS信息

ffmpeg播放rtp流&#xff0c;为了降低首开延迟&#xff0c;需要在SDP文件中指定PPS、SPS、VPS信息。抓包后发现wireshark无法解析AP包。需要自己进行AP包解析。RTP协议AP包格式如下&#xff1a; 根据如上信息&#xff0c;我们可以解析AP包&#xff0c;效果如下 40 01&#xff…

图像质量评估:使用 SSIM 计算图像相似性

在图像处理领域&#xff0c;衡量两幅图像之间相似性的一种常见方法是使用结构相似性指数&#xff08;SSIM&#xff09;。SSIM 是一种全参考的图像质量评估指标&#xff0c;它不仅考虑了图像的亮度、对比度&#xff0c;还考虑了结构信息。在本文中&#xff0c;我们将介绍一个使用…

【Vue2+3入门到实战】(13)插槽<slot>详细示例及自定义组件的创建与使用代码示例 详解

目录 一、学习目标1.插槽2.综合案例&#xff1a;商品列表 一、插槽-默认插槽1.作用2.需求3.问题4.插槽的基本语法5.代码示例6.总结 二、插槽-后备内容&#xff08;默认值&#xff09;1.问题2.插槽的后备内容3.语法4.效果5.代码示例 三、插槽-具名插槽1.需求2.具名插槽语法3.v-s…

【JAVA】使用OPENGL

从这个网址下载对应的库&#xff1a; LWJGL - Lightweight Java Game Libraryhttps://www.lwjgl.org/browse/release/3.3.3下载这个压缩包&#xff08;实际上有很多版本3.3.3是比较新的版本&#xff1a;LWJGL - Lightweight Java Game Library&#xff09;&#xff1a; https…

关于log4j的那些坑

背景&#xff1a;工程中同时存在log4j.xml&log4j2.xml maven依赖如下&#xff1a; 此时工程实际使用的日志文件为log4j.xml 1、当同时设置log4j和log4j2的桥接依赖时 maven依赖如下&#xff1a; 此时启动会有警告日志&#xff1a; 点击告警日志链接&#xff1a;https://…

【Vue2 + ElementUI】el-table中校验表单

一. 案例 校验金额 阐述&#xff1a;校验输入的金额是否正确。如下所示&#xff0c;点击【编辑图标】会变为input输入框当&#xff0c;输入金额。当输入框失去焦点时&#xff0c;若正确则调用接口更新金额且变为不可输入状态&#xff0c;否则返回不合法金额提示 <templat…

Java Stream流轻松遍历树形结构

在日常开发中&#xff0c;经常会遇到返回树形及遍历树形结构的需求&#xff0c;比如构建菜单&#xff0c;项目-任务树形结构&#xff0c;角色权限树形结构等。数据库一般使用parent_id来表示上一层级&#xff0c;遍历的时候一般使用递归或多层for循环&#xff0c;增加了数据库的…

计算机网络复习4

网络层——点到点 文章目录 网络层——点到点功能路由算法IPV4NAT 网络地址转换子网划分与子网掩码、CIDR地址解析协议ARP&#xff1a;根据IP地址找到MAC地址动态主机配置协议DHCP网际控制报文协议ICMPIPV6内部网关协议&#xff08;IGP&#xff09;外部网关协议(EGP) 功能 异构…

数字人直播系统——打破时空限制的新媒体时代

随着科技的不断进步&#xff0c;新媒体开始逐渐成为人们获取信息和娱乐的首选方式。其中&#xff0c;数字人直播系统作为一种创新的传媒形式&#xff0c;正以其独特的优势受到越来越多人的关注和喜爱。数字人直播系统通过将虚拟人物与现实世界紧密结合&#xff0c;打破了时间和…