4 种策略让 MySQL 和 Redis 数据保持一致

先阐明一下 MySQL 和 Redis 的关系:MySQL 是数据库,用来持久化数据,一定程度上保证数据的可靠性;Redis 是用来当缓存,用来提升数据访问的性能。

关于如何保证 MySQL 和 Redis 中的数据一致(即缓存一致性问题),这是一个非常经典的问题。

使用过缓存的人都应该知道,在实际应用场景中,要想实时刻保证缓存和数据库中的数据一样,很难做到。

基本上都是尽可能让他们的数据在绝大部分时间内保持一致,并保证最终是一致的。

1、缓存不一致是如何产生的

如果数据一直没有变更,那么就不会出现缓存不一致的问题。

通常缓存不一致是发生在数据有变更的时候。因为每次数据变更你需要同时操作数据库和缓存,而他们又属于不同的系统,无法做到同时操作成功或失败,总会有一个时间差。在并发读写的时候可能就会出现缓存不一致的问题(理论上通过分布式事务可以保证这一点,不过实际上基本上很少有人这么做)。

虽然没办法在数据有变更时,保证缓存和数据库强一致,但对缓存的更新还是有一定设计方法的,遵循这些设计方法,能够让这个不一致的影响时间和影响范围最小化。

2、缓存更新的几种设计

缓存更新的设计方法大概有以下四种:

先删除缓存,再更新数据库(这种方法在并发下最容易出现长时间的脏数据,不可取)

先更新数据库,删除缓存(Cache Aside Pattern)

只更新缓存,由缓存自己同步更新数据库(Read/Write Through Pattern)

只更新缓存,由缓存自己异步更新数据库(Write Behind Cache Pattern)

接下来详细介绍一些这四种设计方法

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

这种方法在并发读写的情况下容易出现缓存不一致的问题
在这里插入图片描述
如上图所示,其可能的执行流程顺序为:

客户端1 触发更新数据A的逻辑

客户端2 触发查询数据A的逻辑

客户端1 删除缓存中数据A

客户端2 查询缓存中数据A,未命中

客户端2 从数据库查询数据A,并更新到缓存中

客户端1 更新数据库中数据A

可见,最后缓存中的数据 A 跟数据库中的数据 A 是不一致的,缓存中的数据A是旧的脏数据。

因此一般不建议使用这种方式。

2.2 先更新数据库,再让缓存失效

这种方法在并发读写的情况下,也可能会出现短暂缓存不一致的问题
在这里插入图片描述
如上图所示,其可能执行的流程顺序为:

客户端1 触发更新数据A的逻辑

客户端2 触发查询数据A的逻辑

客户端3 触发查询数据A的逻辑

客户端1 更新数据库中数据A

客户端2 查询缓存中数据A,命中返回(旧数据)

客户端1 让缓存中数据A失效

客户端3 查询缓存中数据A,未命中

客户端3 查询数据库中数据A,并更新到缓存中

可见,最后缓存中的数据A和数据库中的数据 A
是一致的,理论上可能会出现一小段时间数据不一致,不过这种概率也比较低,大部分的业务也不会有太大的问题。

2.3 只更新缓存,由缓存自己同步更新数据库(Read/Write Through Pattern)

这种方法相当于是业务只更新缓存,再由缓存去同步更新数据库。一个Write Through的 例子如下:
在这里插入图片描述
如上图所示,其可能执行的流程顺序为:

客户端1 触发更新数据 A 的逻辑

客户端2 触发查询数据 A 的逻辑

客户端1 更新缓存中数据 A,缓存同步更新数据库中数据 A,再返回结果

客户端2 查询缓存中数据 A,命中返回

Read Through 和 WriteThrough 的流程类似,只是在客户端查询数据A时,如果缓存中数据A失效了(过期或被驱逐淘汰),则缓存会同步去数据库中查询数据A,并缓存起来,再返回给客户端。

这种方式缓存不一致的概率极低,只不过需要对缓存进行专门的改造。

2.4 只更新缓存,由缓存自己异步更新数据库(Write Behind Cache Pattern)

这种方式性详单于是业务只操作更新缓存,再由缓存异步去更新数据库,例如:
在这里插入图片描述
如上图所示,其可能的执行流程顺序为:

客户端1 触发更新数据 A 的逻辑

客户端2 触发查询数据 A 的逻辑

客户端1 更新缓存中的数据 A,返回

客户端2 查询缓存中的数据 A,命中返回

缓存异步更新数据 A 到数据库中

这种方式的优势是读写的性能都非常好,基本上只要操作完内存后就返回给客户端了,但是其是非强一致性,存在丢失数据的情况。

如果在缓存异步将数据更新到数据库中时,缓存服务挂了,此时未更新到数据库中的数据就丢失了。
总结

上面讲到的几种缓存更新的设计方式,都是前人总结出来的经验,这些方式或多或少都有一些弊端,并不完美,实际上也很难有完美的设计。大家在做系统设计的时候,也不要去追求完美,要有一些取舍,找到一种最适合自己业务场景的方式就行。

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

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

相关文章

备战蓝桥杯---树形DP基础1

我们先来看几个比较简单的例子来引入: 我们令f[i]表示以i为根节点的子树大小,易得状态转移方程为: f[i]1f[son1]....f[soni]; 我们用DFS即可,下面是大致的模板: 让我们来看看几道题吧: 1.贪心树形DPDFS&…

基于java springmvc+mybatis学生考试系统设计和实现

基于java springmvcmybatis学生考试系统设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言 文末获取…

Unity2023.1.19_Embedded Browser-ZFBrowser插件

Unity2023.1.19_Embedded Browser-ZFBrowser插件 官方说明文档可以仔细看一下: ZFBrowser Documentation (zenfulcrum.com) ZFBrowser插件的简单直接使用: 导入插件包资源,遵循常规导包原则即可; 抓取包文件夹下的预制体组件…

动态规划:万变不离其宗,带你吃透股票系列问题

前言: 对于买卖股票问题而言,最关键的是我们对问题的处理方式(对于每一天而言,我们应该描述当天买入卖出还是只描述每天股票的只有或者不持有的状态呢?)我们应该描述每天股票是否持有的状态,因…

【论文阅读】基于人工智能目标检测与跟踪技术的过冷流沸腾气泡特征提取

Bubble feature extraction in subcooled flow boiling using AI-based object detection and tracking techniques 基于人工智能目标检测与跟踪技术的过冷流沸腾气泡特征提取 期刊信息:International Journal of Heat and Mass Transfer 2024 级别:EI检…

等保测评与商用密码共铸工控安全“双评合规”新篇章

最近听说了一个段子:“网络安全就像美女的内衣,等保和密评就是最贴身的内衣两件套,上下身一件都不能少。否则你的魔鬼身材(核心数据)就有可能被色狼(黑客)一览无余(数据泄漏&#xf…

将SU模型导入ARCGIS,并获取高度信息,多面体转SHP文件(ARCMAP)

问题:将Sketchup中导出的su模型,导入arcgis并得到面shp文件,进而获取各建筑的高度、面积等信息。 思路: (1)导入arcgis得到多面体 (2)转为面shp文件 (3)计算高度/面积等 1、【3D Analyst工具】【转换】【由文件转出】【导入3D文件】(在此步骤之间,建议先建立一个…

学习磁盘管理

文章目录 一、磁盘接口类型二、磁盘设备的命名三、fdisk分区四、自动挂载五、扩容swap六、GPT分区七、逻辑卷管理八、磁盘配额九、RAID十、软硬链接 一、磁盘接口类型 IDE、SATA、SCSI、SAS、FC(光纤通道) IDE, 该接口是并口。SATA, 该接口是串口。SCS…

linux系统---nginx(2)rewrite重写功能

目录 一、rewrite概述 1、rewrite功能 2、跳转场景 二、标准配置指令 1、rewrite日志记录指令 2、未初始化变量告警日志记录指令 3、rewrite 指令 3.1 正则表达式 三、rewrite模块使用实例 1.基于域名的跳转 一、rewrite概述 1、rewrite功能 访问重写 rewrite 是 …

分布式事务(7)之Seata简介

一、分布式事务解决方案 2PC即两阶段提交协议,是将整个事务流程分为两个阶段,准备阶段(Prepare phase)、提交阶段(commit phase),2是指两个阶段,P是指准备阶段,C是指提交…

C# 发现同一依赖程序集的不同版本间存在冲突。请将项目文件中的“AutoGenerateBindingRedirects”属性设置为 true

C# 发现同一依赖程序集的不同版本间存在冲突。请将项目文件中的“AutoGenerateBindingRedirects”属性设置为 true Severity Code Description Project File Line Suppression State Warning Found conflicts between different versions of the same dependent assembly. P…

C#区域医院云LIS信息管理系统源码 标本管理、两癌筛查、数据分析、试剂管理

目录 ​编辑 区域医院云LIS系统功能亮点: 云LIS系统功能: 一、 基础管理 二、 前处理(实验室) 三、 标本处理 四、 样本检验 五、 统计报表 六、 质控管理 七、 基本工作流程 区域LIS系统特点&#xff1…

使用logicflow流程图实例

一.背景 需要使用流程引擎开发项目,没有使用flowable、activiti这类的国外流程引擎,想使用国内的引擎二次开发,缺少单例模式的流程画图程序,都是vue、react、angluer的不适合,从网上找了antx6、logicflow、bpmn.js。感…

顺序表的列题(力扣)和旋转数组

文章目录 一.删除有序数组中的重复项(取自力扣) 二.合并两个有序数组(取自力扣) 三.旋转数组(多解法) 前言 见面我们说到了顺序表今天来分享几个有关于顺序表的题目 一.删除有序数组中的重复项&#xff…

The authenticity of host ‘github.com (20.205.243.166)‘ can‘t be established.

1、运行git clone报错: The authenticity of host github.com (20.205.243.166) cant be established. ECDSA key fingerprint is SHA256:p2QAC1TJYererOttrVc98/R1BWERWu3/LiyFdHfQM. Are you sure you want to continue connecting (yes/no/[fingerprint])? 这个…

cmake 构建Qt存在多个子项目的应用

概述:一般在开发UI应用时候我们都会存在多个子项目,比如一个是主UI界面的项目,有些动态库的项目,主UI中用到子项目中的动态库,我们来看看如何利用cmake来构建这样的一个工程,方便我们在跨平台中开发(macos、…

【HarmonyOS】鸿蒙开发之Video组件——第4.2章

Video组件内VideoOptions属性简介 src:设置视频地址。currentProgressRate:设置视频播放倍速,参数说明如下: number|string:只支持 0.75 , 1.0 , 1.25 , 1.75 , 2.0 。P…

智慧物流之道:数据可视化引领全局监控

在智慧物流的背景下,数据可视化催生了物流管理的全新范式。首先,通过数据可视化,物流企业可以实现对整个供应链的全景式监控。下面我就可以可视化从业者的角度,简单聊聊这个话题。 首先,图表和地图的直观展示使决策者能…

Golang使用Swag搭建api文档

1. 简介 Gin是Golang目前最为常用的Web框架之一。 公司项目验收需要API接口设计说明书(Golang后端服务基于Gin框架编写),编写任务自然就落到了我们研发人员身上。 项目经理提供了文档模板,让我们参考模板来手动编写,要…

教机械臂搭积木?《多Agent系统引论》第4章 实用推理Agent 小结

4.0 前言 Agent起作用,不仅仅是逻辑推理的一种、一个过程,还有其他过程在起作用。为了建立贴合实际的Agent,我们需要提出一种新的概念的模型。这就是实用推理型Agent。 4.1 推理分两步 这种Agent把推理的过程分为了两步,一步是理…