如何保证缓存和 MySQL 的双写一致 ?

news2025/1/12 1:05:33

1. 如何保证缓存和 MySQL 的双写一致 ?

        什么叫做如何保证缓存和 MySQL 双写一致,这个问题就是指当应用程序执行写(增删改)操作时,如何保证 Redis 和 MySQL 的数据一致性。

当用户发送请求时,程序的执行流程如下:

要保证 Redis 和 MySQL 的数据一致性,从大的角度来说,无非就两种思路:

1.修改

  • 先修改数据库,再修改 Redis
  • 先修改 Redis,再修改数据库

2.删除

  • 先删除 Redis,再操作数据库
  • 先操作数据库,再删除 Redis

        这四种方式在正常情况下,都可以保证 Redis 和 MySQL 的数据一致性,但是在异常情况下,就只有一种方式才能真正保证 Redis 和 MySQL 的双写一致。

当上述方式,每个方案都是执行了前半部分后,主机掉电了 >>

① 先修改数据库,再修改 Redis(掉电)

        这种方式,Redis 中是旧数据,而 MySQL 中是新数据,当应用程序访问 Redis 时,发现有数据,直接就返回给用户了,显然这种方式是不合理的。

② 先修改 Redis,再修改数据库(掉电)

        这种方式,Redis 中是新数据,而 MySQL 中是旧数据,当应用程序访问 Redis 时,发现有数据,直接就返回给用户了,此时 Redis 和数据库中的数据也不一致,下一次 Redis 还需要从数据库中同步数据的,显然这种方式也不合理。

③ 先删除 Redis,再操作数据库(掉电)      

        这种方式,不管主机有没有掉电,Redis 始终没数据,始终 都是要从数据库中同步数据的,所以这种方式  Redis 和 MySQL 的数据一定是一致的。

④ 先操作数据库,再删除 Redis(掉电)

        这种方式也是行不通的,操作完数据库,主机掉电,此时 Redis 中还是有数据的,而且是旧数据,而 MySQL 中的数据已经更新了,导致双写不一致。

【并发场景下的问题】

        虽然先删除 Redis,再操作数据库,这种方式看似解决了 Redis 和 MySQL 中的双写一致问题,但是它的前提是要在单线程的情况下。

在多线程的场景下,由于操作系统的随机调度,可能会出现以下情况:

  1. 线程 1 执行完删除 Redis,然后时间片用完了,
  2. 线程 2 执行查询操作,由于线程 1 把 Redis 删除了,所以线程 2 拿到了数据库的旧数据,然后时间片用完了,
  3. 线程 1 继续执行更新数据库,并把新数据缓存至 Redis,执行结束,
  4. 线程 2 苏醒,将刚刚查到的数据,缓存一份至 Redis.

此时 Redis 和数据库中的数据又变成不一致了,那该怎办 ?

【解决办法】延时双删

        在线程 2 执行完之后后,再删除一次 Redis,以便下次查询还得走数据库,此时拿到的就是最新的数据了。(此时线程 1 的缓存 Redis  就可以不必执行了)

        如果在面试中碰到这个问题,回到到这里其实已经差不多了,如果遇到了刁钻一点的面试官,那么我们以上看似美好的推理过程,其实还是存在问题的。

面试官问:延时双删是否彻底解决了 Redis 和 MySQL 双写一致的问题 ?

        答案是不一定,它只是最大限度的解决双写一致性问题。因为延时,延长的时间是固定的,而操作系统的调度是随机的,极端情况下,还是可能会存在线程 1 第二次删除操作处在线程 2 的将旧数据缓存至 Redis 这个操作之前。(极端情况下,线程 2  是个饥饿线程)

那这个问题该怎么完美解决 ?

        这个问题我也问过一些大佬,他们给出的结论是从理论上来说,目前没有更好的解决方案,但是前面也说了只有极端情况下,连延时双删都解决不了,因为它发生的概率也是比较小的,所以可以忽略不计了,并且使用延时双删几乎可以解决 99.99% 的双写一致问题了。

        如果硬要追求完美主义,可以给它设置一个过期时间,等到键值过期了,自然会把数据库中新的数据给保存到 Redis 中;

        另外,对于主机掉电,另一半操作没有执行的问题,可以通过加入消息队里欸来解决(保证业务的完整性),消费者再消费任务的时候,即使掉电,下一次还是会继续消费的。

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

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

相关文章

打造完美的跨境电商系统,助力企业海外扩张!

打造理想的跨境电商系统:关键要素和优势 在如今全球化和互联网时代,跨境电商已成为企业迅速发展的必然选择。打造一套完美的跨境电商系统,不仅可以提升企业的国际竞争力,还可以助力企业实现海外市场的扩张和增长。本文将为您介绍…

单片机 (一) 让LED灯 亮

一:硬件电路图 二:软件代码 #include "reg52.h"#define LED_PORT P2void main() {LED_PORT 0x01; // 0000 0001 D1 是灭的 } #include "reg52.h" 这个头文件的作用:包含52 系列单片机内部所有的功能寄存器 三&#…

Vant 4.6.4发布,增加了一些新功能,并修复了一些bug

导读Vant 4.6.4发布,增加了一些新功能,并修复了一些bug等。 新功能 feat(area-data): 更新芜湖的县区数据,由 nivin-studio 在 #12122 中贡献feat(Locale): 添加塞尔维亚语到国际化,由 RogerZXY 在 #12145 中贡献feat(ImagePreview): 添加 c…

线上问诊:业务数据采集

系列文章目录 线上问诊:业务数据采集 文章目录 系列文章目录前言一、环境准备1.Hadoop2.Zookeeper3.Kafka4.Flume5.Mysql6.Maxwell 二、业务数据采集1.数据模拟2.采集通道 总结 前言 暑假躺了两个月,也没咋写博客,准备在开学前再做个项目找…

爬虫selenium获取元素定位方法总结(动态获取元素)

目录 元素 查看元素信息 元素定位 通过元素id定位 通过元素name定位 通过xpath表达式定位 绝对路径 相对路径 通过完整超链接定位 通过部分链接定位 通过标签定位 通过类名进行定位 通过css选择器进行定位 id选择器 class选择器 标签选择器 属性选择器 定位带…

乘积最大子数组

题目链接 乘积最大子数组 题目描述 注意点 -10 < nums[i] < 10nums 的任何前缀或后缀的乘积都 保证 是一个 32-位 整数 解答思路 最初想到求和最大的子数组所用的贪心算法&#xff0c;判断包括该元素时的最大值tmp&#xff0c;再将当前最大值res与tmp比较&#xff0…

“车-路-网”电动汽车充电负荷时空分布预测(matlab)

目录 1 主要内容 2 部分代码 3 程序结果 4 下载链接 1 主要内容 该程序参考《基于动态交通信息的电动汽车充电负荷时空分布预测》和《基于动态交通信息的电动汽车充电需求预测模型及其对配网的影响分析》文献模型&#xff0c;考虑私家车、出租车和共用车三类交通工具特性和…

长胜证券:九成注册制公司选择上市标准一,牛股“双高”特征明显

新股注册制施行以来&#xff0c;新股公司可选的上市规范愈加多样化&#xff0c;不同板块、不同上市规范的新股公司亦呈现出不同特征&#xff0c;新股上市后不再呈现“套路化”的上涨行情&#xff0c;新股破发成为常态。数据显现&#xff0c;2022年全年及2023年以来&#xff0c;…

Redis 列表 | Navicat

在最近的博客 文章 中&#xff0c;我们已经了解了 Redis 的六种数据类型。其中&#xff0c;Redis 列表&#xff08;List&#xff09;包含一组字符串&#xff0c;他们按照被添加的顺序进行排序。本文将就列表数据类型进行展开介绍&#xff0c;并且重点介绍一些主要的命令来管理它…

自研分布式IM-HubuIM RFC草案

HubuIM RFC草案 消息协议设计 基本协议 评估标准 【性能】协议传输效率&#xff0c;尽可能降低端到端的延迟&#xff0c;延迟高于200ms用户侧就会有所感知 【兼容】既要向前兼容也要向后兼容 【存储】减少消息包的大小&#xff0c;降低空间占用率&#xff0c;一个字节在亿…

Qt应用开发(拓展篇)——示波器/图表 QCustomPlot

一、介绍 QCustomPlot是一个用于绘图和数据可视化的Qt C小部件。它没有进一步的依赖关系&#xff0c;提供友好的文档帮助。这个绘图库专注于制作好看的&#xff0c;出版质量的2D绘图&#xff0c;图形和图表&#xff0c;以及为实时可视化应用程序提供高性能。 QCustomPl…

温湿度传感器之Modbus TCP相比较Modbus RTU的优势

1) 当多个网关共同接一个后台服务器&#xff0c;而一个网关下挂接多个485设备时&#xff0c;如果不同的网关挂接同样地址号的485设备时那么后台服务器无法区分是哪个485从设备&#xff0c;并且最多只能限制485设备个数254个&#xff0c;而modbus-tcp协议包含自定义报文头4个字节…

什么是NetDevOps

NetDevOps 是一种新兴的方法&#xff0c;它结合了 NetOps 和 DevOps 的流程&#xff0c;即将网络自动化集成到开发过程中。NetDevOps 的目标是将虚拟化、自动化和 API 集成到网络基础架构中&#xff0c;并实现开发和运营团队之间的无缝协作。 开发运营&#xff08;DevOps&…

网站和API支持HTTPS,最好在Nginx上配置

随着我们网站用户的增多&#xff0c;我们会逐渐意识到HTTPS加密的重要性。在不修改现有代码的情况下&#xff0c;要从HTTP升级到HTTPS&#xff0c;让Nginx支持HTTPS是个很好的选择。今天我们来讲下如何从Nginx入手&#xff0c;从HTTP升级到HTTPS&#xff0c;同时支持静态网站和…

GEE-PIE遥感大数据处理技术

随着航空、航天、近地空间等多个遥感平台的不断发展&#xff0c;近年来遥感技术突飞猛进。由此&#xff0c;遥感数据的空间、时间、光谱分辨率不断提高&#xff0c;数据量也大幅增长&#xff0c;使其越来越具有大数据特征。对于相关研究而言&#xff0c;遥感大数据的出现为其提…

机器学习深度学习——针对序列级和词元级应用微调BERT

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——NLP实战&#xff08;自然语言推断——注意力机制实现&#xff09; &#x1f4da;订阅专栏&#xff1a;机…

独立站怎么搭建?看这一篇就够了!强烈建议收藏!

独立站是跨境卖家对外销售的一个重要渠道&#xff0c;也是品牌塑造和品牌宣传的重要阵地。那么新手如何从0到1搭建出一个属于自己的独立站呢&#xff1f; 01.购买域名&#xff1a; 域名就相当于是一个网站的门牌号&#xff0c;是独立站的重要组成部分。卖家可以选择自己注册&…

C语言:指针(超深度讲解)

目录 指针&#xff1a; 学习目标&#xff1a; 指针可以理解为&#xff1a; 字符指针&#xff1a; 定义&#xff1a;字符指针 char*。 字符指针的使用&#xff1a; 练习&#xff1a; 指针数组&#xff1a; 概念&#xff1a;指针数组是一个存放指针的数组。 实现模拟二维…

【0基础入门Python Web笔记】四、python 之计算器的进阶之路

四、python 之计算器的进阶之路 往期导航越来越智能的加法计算器加减乘除计算器来点课程作业&#xff1f;更多实战项目可进入下方官网 往期导航 一、python 之基础语法、基础数据类型、复合数据类型及基本操作 二、python 之逻辑运算和制流程语句 三、python 之函数以及常用内…

服务器中了Cylance勒索病毒,数据该怎么恢复?

近日&#xff0c;在市面上出现了一种名为Cylance的勒索病毒。经过云天数据恢复中心技术工程师对比分析后发现&#xff0c;该病毒不属于已知的任何勒索病毒家族中的成员&#xff0c;属于一种新型的勒索病毒&#xff0c;那接下来我们分析一下这种勒索病毒。 中了Cylance勒索病毒的…