使用缓存时,先操作数据库 or 先操作缓存

使用缓存时,先操作数据库 or 先操作缓存?谈谈你的见解。

如何上面是一道面试题,你要如何回答,一个去团团面试的同学回来告诉我,一个问题带出一串问题,回答不好,直接作废,换句话说,刷面试题的同学要注意了,要一串一串的刷,把相关连的问题串起来,如果只是单个问题,你会很快暴露。

在使用缓存的场景中,先操作数据库还是先操作缓存取决于具体的业务需求和性能目标。以下是两种常见的策略:

  1. 先操作数据库,再操作缓存:
  • 优点:确保数据的一致性和准确性。当数据更新时,首先更新数据库,然后更新缓存,这样可以保证缓存中的数据总是与数据库同步。
  • 缺点:在高并发场景下,可能会因为缓存更新操作的延迟导致短暂的数据不一致问题。
  • 适用场景:对数据一致性要求较高的场景,如金融交易、订单处理等。
  1. 先操作缓存,再操作数据库:
  • 优点:提高系统性能和响应速度。当数据读取时,首先从缓存中获取数据,这样可以减少对数据库的直接访问,降低数据库的压力。
  • 缺点:如果操作缓存成功但数据库操作失败,会导致缓存与数据库的数据不一致。
  • 适用场景:对性能要求较高,可以容忍短暂的数据不一致的业务场景,如内容展示、用户信息展示等。

两种方法各有优缺点,V 哥来具体分析一下(部分内容来自网络):

先操作数据库

假如有两个并发的请求,一个写请求,一个读请求,流程如下:

可能存在的脏数据时间范围:更新数据库后,失效缓存前。这个时间范围很小,通常不会超过几毫秒。

先操作缓存

假如有两个并发的请求,一个写请求,一个读请求,流程如下:

可能存在的脏数据时间范围:更新数据库后,下一次对该数据的更新前。这个时间范围不确定性很大,情况如下:

  • 如果下一次对该数据的更新马上就到来,那么会失效缓存,脏数据的时间就很短。
  • 如果下一次对该数据的更新要很久才到来,那这期间缓存保存的一直是脏数据,时间范围很长。

结论:通过上述案例可以看出,先操作数据库和先操作缓存都会存在脏数据的情况。但是相比之下,先操作数据库,再操作缓存是更优的方式,即使在并发极端情况下,也只会出现很小量的脏数据。

让缓存失效,而不是更新缓存

先来看更新缓存的案例:

有两个并发的写请求,流程如下:

分析:数据库中的数据是请求B的,缓存中的数据是请求A的,数据库和缓存存在数据不一致。

再来看失效(删除)缓存的案例:

有两个并发的写请求,流程如下:

分析:由于是删除缓存,所以不存在数据不一致的情况。
结论:通过上述案例,可以很明显的看出,失效缓存是更优的方式。

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

上面的案例中,无论是先操作数据库,还是先操作缓存,都会存在脏数据的情况,有办法避免吗?

答案是有的,由于数据库和缓存是两个不同的数据源,要保证其数据一致性,其实就是典型的分布式事务场景,可以引入分布式事务来解决,常见的有:2PC、TCC、MQ事务消息等。

但是引入分布式事务必然会带来性能上的影响,这与我们当初引入缓存来提升性能的目的是相违背的。

所以在实际使用中,通常不会去保证缓存和数据库的强一致性,而是做出一定的牺牲,保证两者数据的最终一致性。

如果是实在无法接受脏数据的场景,则比较合理的方式是放弃使用缓存,直接走数据库。

保证数据库和缓存数据最终一致性的常用方案如下:

  • 更新数据库,数据库产生 binlog。
  • 监听和消费 binlog,执行失效缓存操作。
  • 如果步骤2失效缓存失败,则引入重试机制,将失败的数据通过MQ方式进行重试,同时考虑是否需要引入幂等机制。

兜底:当出现未知的问题时,及时告警通知,人为介入处理。

人为介入是终极大法,那些外表看着光鲜艳丽的应用,其背后大多有一群苦逼的程序员,在不断的修复各种脏数据和bug。

小结一下

在某些情况下,让缓存失效而不是更新缓存是一种常见的做法,主要基于以下几个原因:

  • 复杂性:更新缓存可能涉及到复杂的逻辑,特别是当缓存的数据结构和数据库中的数据结构不一致时。让缓存失效则简单得多,只需删除缓存项。

  • 一致性:在分布式系统中,保持缓存和数据库之间的一致性可能非常复杂。如果系统中有多个缓存节点,更新所有节点的缓存以保证一致性可能代价很高。让缓存失效可以确保所有节点在下一次请求时从数据库获取最新的数据。

  • 性能:更新缓存可能涉及到多个步骤,如读取旧值、计算新值、写入新值等,这可能会增加系统的延迟。让缓存失效后,直接从数据库读取数据,虽然可能会增加数据库的负载,但可以减少缓存更新的复杂性和潜在的延迟。

  • 容错性:在某些情况下,更新缓存可能会失败,导致缓存中的数据不一致。让缓存失效是一种更安全的策略,因为它减少了失败的可能性。

  • 缓存穿透:如果一个不存在的数据被频繁查询,更新缓存意味着每次查询都会去数据库查找,这可能导致数据库的负载增加。让缓存失效可以避免这种情况,通过设置一个短暂的过期时间,可以减少对数据库的压力。

  • 数据变更频率:如果数据变更非常频繁,频繁更新缓存可能导致缓存命中率降低,从而降低缓存的效率。在这种情况下,让缓存失效可以提高缓存的效率。

  • 缓存过期策略:许多缓存系统已经内置了过期策略,这意味着缓存项会在一定时间后自动失效。利用这一特性,可以让缓存失效成为一种自然而有效的更新机制。

  • 简化设计:让缓存失效可以简化系统设计,因为开发者不需要考虑缓存数据的更新逻辑,只需要处理缓存失效后的逻辑即可。

所以让缓存失效是一种简单、有效且安全的策略,尤其适用于那些对数据一致性要求不是特别高、数据变更频繁或者系统设计需要简化的场景。然而,这并不意味着更新缓存没有用武之地,在某些需要保证数据实时性和一致性的场景下,更新缓存仍然是必要的。

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

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

相关文章

某红书旋转滑块验证码分析与协议算法实现(高通过率)

文章目录 1. 写在前面2. 接口分析3. 验证轨迹4. 算法还原 【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致…

C2M商业模式分析与运营平台建设解决方案(52页PPT)

方案介绍: C2M商业模式通过直接连接消费者与制造商,实现了个性化定制和高效生产。运营平台建设解决方案则注重技术选型、数据驱动、用户体验和供应链管理等方面,为C2M模式的顺利实施提供了有力支持。随着数字化时代的到来,C2M模式…

解决git status提示error bad signature 0x00000000

问题描述: 操作git的时候电脑卡了,重启电脑后git status就提示bad signature 0x00000000,index file corrupt错误,如下: 解决办法: rm -f .git/index git reset

计网期末复习指南(三):数据链路层(CRC冗余校验码计算、PPP协议、CSMA/CD协议、交换机的自学习能力、VLAN)

前言:本系列文章旨在通过TCP/IP协议簇自下而上的梳理大致的知识点,从计算机网络体系结构出发到应用层,每一个协议层通过一篇文章进行总结,本系列正在持续更新中... 计网期末复习指南(一):计算…

【wiki知识库】04.SpringBoot后端实现电子书的增删改查以及前端界面的展示

📝个人主页:哈__ 期待您的关注 目录 一、🔥今日内容 二、🌏前端页面的改造 2.1新增电子书管理页面 2.2新增路由规则 2.3修改the-header代码 三、🚗SpringBoot后端Ebook模块改造 3.1增加电子书增/改接口 3.1.…

Cacti EZ中文版 12.2.27 ISO 下载安装

简介 修改了yum源为中国高校联合镜像源 github改为gitee。 系统增加中文语言包。 修改时区为东八区。 增加了常用的软件包。 PS:CactiEZ是一个自动化安装cacti和插件的ISO镜像,本教程的ISO是基于官方的IOS针对国内网络做了修改。 可按照目前最新的Ca…

[AI Google] 新的生成媒体模型和工具,专为创作者设计和构建

我们推出了 Veo,我们最强大的高清晰度视频生成模型,以及 Imagen 3,我们质量最高的文本生成图像模型。我们还分享了一些使用我们的 Music AI Sandbox 创作的新演示录音。 在过去的一年里,我们在提升生成媒体技术质量方面取得了令人…

智能售货机的小投入大回报创业机遇

智能售货机的小投入大回报创业机遇 在当今这个快速进化的数字时代,智能售货机作为零售领域的新秀,正以其独特的便捷性和创新性逐步重塑传统零售格局。24小时不间断服务与自动化管理的结合,大幅度削减人力成本,使得智能售货机成为…

生信算法7 - 核酸序列Fasta和蛋白PDB文件读写与检索

python 3.9实现以下算法。 1. 简单的写文件和读文件 # 写 file1 open(count.txt,w) file1.write(this is a test) file1.close()# 读 file2 open(my_file) print(file2.read())2. 将列表内容写入文本文件 # 生成100-500数字列表 data [i * 100 for i in range(1, 6)] pri…

AI大模型,正在排队寻求“卖身”!请保持冷静!

AI独角兽卖身大潮,再添一员 就在上周,备受瞩目的明星企业Stability AI,这家估值接近300亿的大模型领域的佼佼者,**突然传出资金链断裂的严峻消息,并正积极寻求合并的可能性。**与此同时,媒体也透露&#x…

RetroMAE-文本embedding算法

1)输入文本经掩码操作后由编码器(Encoder)映射为隐空间中的语义向量;而后解码器(Decoder)借助语义向量将另一段独立掩码的输入文本还原为原始的输入文本 2)编码器的掩码率为15%-30%;解码器的掩码率为50%-70…

HMM地图匹配算法库Barefoot环境搭建

1.引入gps路径匹配开源项目barefoot 克隆仓库 git clone https://github.com/bmwcarit/barefoot.git打开项目执行mvn命令将项目打包到maven仓库 mvn install -DskipTests在自己的maven项目中引入barefoot依赖 <dependency><groupId>com.bmw-carit</groupId&g…

k8s 1.28.x 配置nfs

1.安装nfs&#xff0c;在每个节点上安装 yum install -y nfs-utils 2.创建共享目录(主节点上操作) mkdir -p /opt/nfs/k8s 3.编写NFS的共享配置 /opt/nfs/k8s *(rw,no_root_squash) #*代表对所有IP都开放此目录&#xff0c;rw是读写 4.启动nfs systemctl enable nfs-ser…

Flutter基础 -- Dart 语言 -- 进阶使用

目录 1. 泛型 generics 1.1 泛型使用 1.2 泛型函数 1.3 构造函数泛型 1.4 泛型限制 2. 异步 async 2.1 异步回调 then 2.2 异步等待 await 2.3 异步返回值 3. 生成器 generate &#xff08;了解&#xff09; 3.1 同步生成器 sync* 使用 sync* 的场景 总结 3.2 异…

CRM系统主要是干什么?CRM系统主要功能和作用

什么是CRM 系统&#xff1f;CRM系统到底是干什么的&#xff1f;不同的企业人员该如何利用CRM去解决他们的问题等等&#xff0c;问题太多了&#xff0c;今天来为大家详细介绍。 干货满满&#xff0c;建议收藏&#xff01;&#xff01; 首先第一个问题&#xff0c;什么是CRM系统…

Tween.js在Three.js中的应用:为3D动画添加流畅过渡

前言 在Web开发领域&#xff0c;Three.js已经成为构建精彩3D内容的首选库之一。它让开发者能够轻松地在浏览器中创建和展示复杂的3D场景。然而&#xff0c;要让这些场景栩栩如生&#xff0c;平滑的动画效果是必不可少的。这就引入了Tween.js——一个轻量级但功能强大的JavaScr…

MyBatis核心对象

MyBatis核心类对象主要有俩个&#xff1a; 1&#xff1a;对相关配置文件信息进行封装的Configuration对象 2&#xff1a;用来执行数据库操作的Executor对象。 核心对象----存储类对象Configuration Configuration对象主要有三个作用&#xff1a; 1&#xff1a;封装MyBatis…

linux进程加载和启动过程分析

我们的源代码通过预处理,编译,汇编,链接后形成可执行文件,那么当我们在终端敲下指令$ ./a.out argv1 argv2 后,操作系统是怎么将我们的可执行文件加载并运行的呢? 首先知道,计算机的操作系统的启动程序是写死在硬件上的,每次计算机上电时,都将自动加载启动程序,之后…

R语言数据分析-针对芬兰污染指数的分析与考察

1. 研究背景及意义 近年来&#xff0c;随着我国科技和经济高速发展&#xff0c;人们生活质量也随之显著提高。但是&#xff0c; 环境污染问题也日趋严重&#xff0c;给人们的生活质量和社会生产的各个方面都造成了许多不 利的影响。空气污染作为环境污染主要方面&#xff0c;更…

重生之我要精通JAVA--第七周笔记

文章目录 IO流字符流字符流原理解析flush和close方法 文件拷贝代码文件加密解密修改文件中的数据 缓冲流字节缓冲流字符缓冲流例题 转换流序列化流序列化流/对象操作输出流 反序列化流序列化流/反序列化流的细节汇总打印流字节打印流字符打印流 解压缩流压缩流Commons-io常见方…