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

news2024/11/25 19:23:40

一、什么是数据库和缓存双写一致性?

在分布式系统中,数据库和缓存会搭配一起使用,以此来保证程序的整体查询性能。也就说,分布式系统为了缓解数据库查询的压力,会将查出来的数据保存在缓存中,下次再查询时,直接走缓存系统,而不再查询数据库,这样就极大的提高了整体的查询性能。

1.1 为什么缓存比数据库快?

缓存之所以比数据库快的主要原因有以下 3 点:

  • 内存访问速度快:缓存通常将数据存储在内存中,而数据库将数据存储在磁盘上。相比于磁盘访问,内存访问速度更快,可以达到纳秒级别的读取速度,远远快于数据库的毫秒级别的读取速度。

  • IO 操作次数少:数据库通常需要进行磁盘 IO 操作,包括读取和写入磁盘数据。而缓存将数据存储在内存中,避免了磁盘 IO 的开销。内存访问不需要进行磁盘寻址和机械运动,相对来说速度更快。

  • 特殊的数据结构:缓存的数据结构通常为 key-value 形式的,也就是说缓存可以做到任何数据量级下的查询数据复杂度为 O(1),所以它的查询效率是非常高的;而数据库采用的是传统数据结构设计,可能需要查询二叉树、或全文搜索、或回表查询等操作,所以其查询性能是远低于缓存系统的。

1.2 缓存一致性问题

虽然缓存可以极大的提高查询性能,但同时也带来的新的问题:数据库和缓存一致性的问题。

具体来说,在一个常见的应用场景中,当更新数据库的操作完成后,需要同步更新缓存,以保证缓存中的数据与数据库中的数据保持一致。然而,由于数据库和缓存是两个不同的组件,它们的数据更新操作是异步的,可能存在以下问题:

  1. 数据延迟:数据库更新和缓存更新之间存在时间延迟,导致缓存中的数据不是最新的。这可能会引起数据的不一致,当其他请求读取数据时,可能会读取到旧的数据。

  2. 更新失败:在尝试更新缓存时,可能出现更新失败的情况。例如,缓存节点暂时不可用,网络故障等。如果更新缓存失败而未进行适当的处理,也会导致数据库和缓存之间的数据不一致。

也就说,因为以上原因,可能会导致 A 用户和 B 用户执行了同一个查询操作,但是得到了完全不同的结果,这就是数据库和缓存的一致性问题。


二、如何解决双写一致性问题?

解决缓存和数据库一致问题的常见解决方案有以下 4 种:

  1. 先修改数据库,后更新缓存。

  2. 先更新缓存,后修改数据库。

  3. 先修改数据库,后删除缓存。

  4. 先删除缓存,后修改数据库。

然而,前 3 种解决方案,有同一个问题,也就是当第一步操作执行完之后,第二步未执行的情况下,就会导致数据库和缓存的一致性问题,例如第一步执行完之后,系统掉电了,那么一致性问题就会一直存在。

相比之下,第 4 种解决方案(先删除缓存,后修改数据库)相比于前三种解决方案更有优势,起码它保证了双方都未执行成功,那么从数据一致性层面来讲,第 4 种方案起码保证了一定的数据一致性,然而第 4 种执行方案依然存在其他问题,例如以下这几个:

  1. 业务完整性问题:程序只执行了一半,第一步执行完了但第二步未执行的情况。

  2. 并发保存旧值的问题:在并发环境下,第四种方案可能会导致缓存保存旧值的情况,例如以下执行情况:


三、消息队列 + 延迟双删策略

双写一致性问题的最终解决方案是:消息队列 + 延迟双删策略。

3.1 为什么要使用消息队列?

因为消息队列里面有消息确认机制,它可以保证我们执行完第一步之后,即时掉电重启的情况,依然可以执行后续的流程,因为之前的消息,未进行消息确认,所以程序重启之后,会继续执行后续的流程,这样就保证了业务执行的完整性。

3.2 什么是延迟双删?

延迟双删指的是删除两次缓存(并且最后一次是延迟删除),具体执行流程如下:

  1. 删除缓存

  2. 更新数据库

  3. 延迟一会再删除缓存

最后一次延迟删除缓存的原因是,为了避免上面因为并发问题导致保存旧值的情况发生,所以会延迟一段时间之后再进行删除操作。这样即使有并发问题,也能最大限度的解决保存旧值的情况,因为是延迟之后删除的,所以即使因为并发问题保存了旧值,但延迟一段时间之后旧值就会被删除,那么这样就自然而然的保证了数据库和缓存的最终一致性。

总结

数据库和缓存双写一致性问题是一道经典的面试题,最初解决方案是先更新数据库、再删除缓存,然而如果发生掉电情况,只执行了前一步操作,那么缓存和数据库就出现了不一致性的问题。为了解决这个问题,所以通常会采用延迟双删 + 消息队列来保证业务的完整执行和数据一致性问题。

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

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

相关文章

【送书活动二期】Java和MySQL数据库中关于小数的保存问题

之前总结过一篇文章mysql数据库:decimal类型与decimal长度用法详解,主要是个人学习期间遇到的mysql中关于decimal字段的详解,最近在群里遇到一个小伙伴提出的问题,也有部分涉及,今天就再大致总结一下Java和MySQL数据库…

SpringCloudAlibaba之Nacos——详细讲解

目录 一、SpringCloudAlibaba简介 1. spring cloud alibaba 特点 2.springcloud 组件 二、环境搭建 1.构建项目并引入依赖 三、Nacos 1.什么是Nacos 2.安装Nacos 3.启动安装服务 4.访问nacos的web服务管理界面 四、开发服务注册到nacos 1.创建项目并引入依赖 2.配置注册地…

idea 导入外部包 打包失败

一、在项目中引入jar包 二、pom文件添加 引入外部包 <!--应用第三方包监听文件--><dependency><groupId>jnotify</groupId><artifactId>jnotify</artifactId><version>0.94.0</version><scope>system</scope><…

LDF文件之LDF Explorer工具

LDF Explorer工具 LDF文件比较像DBC文件&#xff0c;也是用来解析报文的&#xff0c;DBC文件是用在CAN通讯上的&#xff0c;LDF文件是用在LIN通讯上的。 我们可以用vector自带的工具LDF Explorer打开LDF文件&#xff0c;这个工具是最标准的&#xff0c;有些同学自己做了一个L…

西工大网络空间安全学院计算机系统基础实验零

首先&#xff0c;下载VMware17 Pro workstation。为什么要下载VMware17 Pro workstation呢&#xff1f;因为计算机系统基础实验有四个大部分&#xff1a;利用位运算实现诸如a*b&#xff0c;a/b&#xff0c;a*(2^4)等运算&#xff1b;C语言循环语句、switch语句等语句与汇编代码…

Linux基本指令总结(二)

1.man指令&#xff08;重要&#xff09; Linux的命令有很多参数&#xff0c;我们不可能全记住&#xff0c;我们可以通过查看联机手册获取帮助。访问Linux手册页的命令是 man 语法: man [选项] 命令 man指令就相当于一个精通linux的专家&#xff0c;你要查询的指令或者函数&…

正式版PS 2024 25新增功能 刚刚发布的虎标正式版

Adobe Photoshop 2024是一款业界领先的图像编辑软件&#xff0c;被广泛应用于设计、摄影、插图等领域。以下是这款软件的一些主要功能和特点&#xff1a; 丰富的工具和功能。Adobe Photoshop 2024提供了丰富的工具和功能&#xff0c;可以帮助用户对图像进行编辑、修饰和优化。…

嵌入式Linux学习(2)——经典CAN介绍(上)

目录 一. CAN与ISO-OSI Model 二. CAN通信 2.1 接线方式 2.1.1 闭环网络 2.1.2 开环网络 2.2 收发流程 2.2.1 发送 2.2.2 接收 三. CAN BUS访问与仲裁 3.1 “线与”机制​ 3.2 仲裁机制 REF CAN&#xff08;Controller Area Network&#xff09;总线协议是由 BOSC…

2024年湖北建筑企业申报助理工程师初级职称评审纸质版证书

2024年湖北建筑企业申报助理工程师初级职称评审纸质版证书 湖北省在2022年就发布了一个相关职称实行电子版文件&#xff0c;很多人就理所当然认为工程行业纸质版初级职称/助理工程师、中级职称有些局限。申报评审成功是否可以使用&#xff0c;怎么查询之类的一系列问题&#x…

C++算法入门练习——数据流第K大元素

现有一个初始为空的序列S&#xff0c;对其执行n个操作&#xff0c;每个操作是以下两种操作之一&#xff1a; 往序列S中加入一个正整数x&#xff1b;输出当前序列S​中第k​大的数。 其中&#xff0c;第k大是指将序列从大到小排序后的第k个数。 利用stl里的priority_queue自动…

【工具使用】Keil常用的调试操作整理介绍

目录 一、软件调试使用 1.1 基本调试操作 1.2 调试窗口 二、注意事项 一、软件调试使用 1.1 基本调试操作 上文已经说过在线调试和模拟调试的配置过程&#xff0c;但无论是在线还是模拟调试&#xff0c;调试技巧工具的使用都是一样的。 点击红色d&#xff0c;进入调试 可…

实时天气(预报)API接口

实时天气预报API接口 一、实时天气(预报)API接口二、使用步骤1、接口2、请求参数3、请求参数示例4、接口 返回示例 三、 如何获取appKey和uid1、申请appKey:2、获取appKey和uid 四、重要说明 一、实时天气(预报)API接口 一款帮助你获取实时天气和天气预报的API接口 二、使用步…

量子计算:探索未来的计算技术

量子计算:探索未来的计算技术 引言 在过去的几十年里,我们见证了计算机技术从简单的计算和存储发展到复杂的数据处理和人工智能的飞速进步。然而,随着我们进一步探索科技的前沿,传统的计算方法开始显示出其局限性。在这种情况下,量子计算——一种基于量子力学原理的新型计…

Redis 基础、字符串、哈希、有序集合、集合、列表以及与 Jedis 操作 Redis 和与 Spring 集成。

目录 1. 数据类型 1.1 字符串 1.2 hash 1.3 List 1.4 Set 1.5 sorted set 2. jedis操作redis 3. 与spring集成 1. 数据类型 1.1 字符串 String是最常用的数据格式&#xff0c;普通的kay-value都归结为此类&#xff0c; value值不仅可以是string&#xff0c;可以是数字…

数据库中生成列的对比

简介 生成列&#xff08;虚拟列&#xff09;&#xff1a;在实际开发中&#xff0c;相对一个历史数据的表增加一个字段&#xff0c;增加下游报表&#xff0c;数据分析的可用性。常见的方法就是删表重建&#xff0c;或者使用ADD column 语法。如果是一个历史表&#xff0c;删…

[问题解决] no CUDA-capable device is detected

先说环境&#xff0c;在docker下的gpu环境ffmpeg&#xff0c;然后今天突然无法使用&#xff0c;使用时出现如下图所示&#xff1a; 看着报错大致内容是找不到设备&#xff0c;网上寻找一番没有有用的东西&#xff0c;于是决定自己解决&#xff0c;仔细察看一番后&#xff0c;猜…

使用netconf配置华为设备

实验目的&#xff1a; 公司有一台CE12800的设备&#xff0c;管理地址位172.16.1.2&#xff0c;现在需要编写自动化脚本&#xff0c;通过SSH登陆到设备上配置netconf协议的用户名&#xff0c;密码以及netconf服务&#xff0c;并且通过netconf协议将设备的loopback0接口IP地址配…

unity程序中的根目录

在unity程序中如果要解析或保存文件时&#xff0c;其根目录为工程名的下一级目录&#xff0c;也就是Assets同级的目标

【数据结构】- 详解线索二叉树(C 语言实现)

目录 一、线索二叉树的基本概念 二、构造线索二叉树 三、遍历线索二叉树 一、线索二叉树的基本概念 遍历二叉树是以一定规则将二叉树中的结点排列成一个线性序列&#xff0c;得到二叉树中结点的先序序列、中序序列或后序序列。这实质上是对一个非线性结构进行线性化操作&am…

【同一局域网下】两台电脑之间互ping

两台电脑互ping 首先需要连接同一网咯关闭需要ping的电脑的防火墙 关闭防火墙步骤&#xff08;以win11系统为例&#xff09;&#xff1a; 设置 --> 隐私和安全性 --> Windows 安全中心 打开Windows安全中心 防火墙和网络保护 --> 选择正在使用的网络 关闭 ping其他…