如何保证MySQL和Redis中的数据一致性?

文章目录

  • 前言
  • 一、缓存案例
    • 1.1 缓存常见用法
    • 1.2 缓存不一致产生的原因
  • 二、解决方案
    • 2.1 先删除缓存,再更新数据库
    • 2.2 先更新数据库,删除缓存
    • 2.3 只更新缓存,由缓存自己同步更新数据库
    • 2.4 只更新缓存,由缓存自己异步更新数据库
    • 2.5 引入 MQ
  • 三、总结

前言

在高并发的场景下,大量的请求直接访问MySQL很容易造成性能瓶颈。所以,我们都会用Redis来做数据的缓存,削减对数据库的压力。但是,MySQL和Redis是两种不同的数据库,如何保证不同数据库之间数据的一致性就非常关键了。

关于MySQL和Redis中的数据一致性问题,可以先说一下结论:没有完美的方案,只有最适合某场景的方案。这个问题表面上看是数据一致性的问题,其实根本上,又是数据一致性、系统性能和系统复杂度的选择与取舍。我们所能做到的是尽可能让它们的数据在绝大部分时间内保持一致,并保证最终是一致的。

一、缓存案例

1.1 缓存常见用法

通常情况下,我们使用缓存的主要目的是为了提升查询的性能。大多数情况下,我们使用缓存的例子如下图。

在这里插入图片描述
1.用户请求过来之后,先查缓存有没有数据,如果有则直接返回。
2.如果缓存没数据,再继续查数据库。
3.如果数据库有数据,则将查询出来的数据,放入缓存中,然后返回该数据。
4.如果数据库也没数据,则直接返回空。

这是缓存非常常见的用法,一眼看上去,好像没有啥问题。但如果数据库中的某条数据,放入缓存之后,又立马被更新了,那么缓存中的数据就和数据库中的数据不一致了。

1.2 缓存不一致产生的原因

如果数据一直没有变更,那么就不会出现Redis和MySQL数据不一致性的问题。

两者之间数据不一致是因为一者发生了数据的变更,另一者如何在短时间内同步数据的问题。因为每次数据变更需要同时操作数据库和缓存,而他们又属于不同的系统,无法做到同时操作成功或失败,总会有一个时间差。在并发读写的时候可能就会出现缓存不一致的问题。

二、解决方案

缓存更新的设计方法大概有5种,下面分别对这四种方案进行描述。

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

  1. 这种方法在并发读写的情况下容易出现缓存不一致的问题。
    在这里插入图片描述

  2. 如上图所示,其可能的执行流程顺序为:
    1.客户端1 触发更新数据A的逻辑
    2.客户端2 触发查询数据A的逻辑
    3.客户端1 删除缓存中数据A
    4.客户端2 查询缓存中数据A,未命中
    5.客户端2 从数据库查询数据A,并更新到缓存中
    6.客户端1 更新数据库中数据A

可见,最后缓存中的数据A跟数据库中的数据A是不一致的,缓存中的数据A是旧的脏数据。因此一般不建议使用这种方式。

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

  1. 这种方法在并发读写的情况下,也可能会出现短暂缓存不一致的问题。
    在这里插入图片描述
  2. 如上图所示,其可能执行的流程顺序为:
    1.客户端1 触发更新数据A的逻辑
    2.客户端2 触发查询数据A的逻辑
    3.客户端3 触发查询数据A的逻辑
    4.客户端1 更新数据库中数据A
    5.客户端2 查询缓存中数据A,命中返回(旧数据)
    6.客户端1 让缓存中数据A失效
    7.客户端3 查询缓存中数据A,未命中
    8.客户端3 查询数据库中数据A,并更新到缓存中

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

2.3 只更新缓存,由缓存自己同步更新数据库

  1. 只更新缓存,再由缓存去同步更新数据库。一个Write Through的例子如下:

在这里插入图片描述

  1. 如上图所示,其可能的执行流程顺序为:
    1.客户端1 触发更新数据A的逻辑
    2.客户端2 触发查询数据A的逻辑
    3.客户端1 更新缓存中的数据A,返回
    4.客户端2 查询缓存中的数据A,命中返回
    5.缓存异步更新数据A到数据库中

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

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

2.4 只更新缓存,由缓存自己异步更新数据库

  1. 只操作更新缓存,再由缓存异步去更新数据库,例如:
    在这里插入图片描述
  2. 如上图所示,其可能的执行流程顺序为:
    1.客户端1 触发更新数据A的逻辑
    2.客户端2 触发查询数据A的逻辑
    3.客户端1 更新缓存中的数据A,返回
    4.客户端2 查询缓存中的数据A,命中返回
    5.缓存异步更新数据A到数据库中

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

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

2.5 引入 MQ

在高并发的业务场景中,MQ(消息队列)是必不可少的技术之一。它不仅可以异步解耦,还能削峰填谷。对保证系统的稳定性是非常有意义的。MQ的生产者生产了消息之后,通过指定的topic发送到MQ服务器。然后MQ的消费者订阅该topic的消息,读取消息数据之后,做业务逻辑处理。使用MQ重试的具体方案如下:

在这里插入图片描述

  1. 当用户操作写完数据库,但删除缓存失败了,产生一条消息,发送给MQ服务器。
  2. 消费者读取MQ消息,重试5次删除缓存。如果其中有任意一次成功了,则返回成功。如果重试了5次,还是失败,则写入死信队列中。
  3. 推荐MQ使用RocketMQ,重试机制和死信队列默认是支持的。使用起来非常方便,而且还支持顺序消息,延迟消息和事务消息等多种业务场景。

当然在该方案中,删除缓存可以完全走异步。即用户的写操作,在写完数据库之后,不用立刻删除一次缓存。而直接发送消息,到MQ服务器,然后有消费者全权负责删除缓存的任务。因为MQ的实时性还是比较高的,因此改良后的方案也是一种不错的选择。

三、总结

1.我们能放入缓存的数据本就不应该是实时性、一致性要求超高的。所以缓存数据的时候加上过期时间,保证能够再容忍的时间段内拿到当前最新数据即可。
2.我们不应该过度设计,增加系统的复杂性。
3.遇到实时性、一致性要求高的数据,就应该查数据库,即使慢点。

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

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

相关文章

内核升级!IvorySQL 3.1 发版

1. 版本介绍 [发行日期:2024年1月26日] IvorySQL 3.1 基于 PostgreSQL 16.1 ,包含来自 PostgreSQL 16.1 的各种修复。有关 PostgreSQL 16.1 中更详细的更新和错误修复,请参阅官方PostgreSQL 16.1 发行说明 。 🔗https://www.po…

MySQL-----DDL基础操作

SQL通用语法 1.SQL语句可以单行或多行书写,以分号结尾。 2. SQL语句可以使用空格/缩进来增强语句的可读性。 3. MySQL数据库的SQL语句不区分大小写,关键字建议使用大写。 4.注释: 单行注释:--注释内容或#注释内容(MySQL特有) 多行注释:/*注释…

【Iot】什么是串口?什么是串口通信?串口通信(串口通讯)原理,常见的串口通信方式有哪些?

串口通信原理 1. 串口2. 串口通信4. 波特率与比特率5. 帧格式3. 串口通讯的通讯协议3.1. RS2323.2. RS485 总结 1. 串口 串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口),是采用串行通信方式的扩展接口。 串口可…

jstack命令解析

前言 如果有一天,你的Java程序长时间停顿,也许是它病了,需要用jstack拍个片子分析分析,才能诊断具体什么病症,是死锁综合征,还是死循环等其他病症,本文我们一起来学习jstack命令~ jstack 的功…

一、cadence PDK 自学笔记-心法

我这边ADS /Cadence PDK基本大部分都是自学完成的。 当然也非常感谢我的前同事周**的帮忙,教了我很多基础的。另外也感谢我现在同事,李**和程*的帮忙,学习了很多cad的视角。 其实对于自学写PDK的小伙伴,一般都要如何学习呢&…

深度学习入门笔记(六)线性回归模型

本节,我们用线性回归为例子,回顾一些基本概念 6.1 相关性 相关性的取值范围是-1 到 1,越接近 1 或者-1 代表越相关,越接近 0 则越不相关。相关系数大于 0 称为正相关,小于 0 称为负相关。 假如 A 与 B 正相关&#…

[UI5 常用控件] 05.FlexBox, VBox,HBox,HorizontalLayout,VerticalLayout

文章目录 前言1. FlexBox布局控件1.1 alignItems 对齐模式1.2 justifyContent 对齐模式1.3 Direction1.4 Sort1.5 Render Type1.6 嵌套使用1.7 组件等高显示 2. HBox,VBox3. HorizontalLayout,VerticalLayout 前言 本章节记录常用控件FlexBox,VBox,HBox,Horizontal…

快速理解复杂系统组成学习内容整合

目录 一、复杂系统组成 二、接入系统 (Access System) 三、应用系统 (Application System) 四、基础平台 (Foundation Platform) 五、中间件 (Abundant External Middleware) 六、支撑系统 (Supporting System) 参考文章 一、复杂系统组成 复杂系统是由多个相互关联、相…

React中的事件处理逻辑

在React中,事件处理逻辑是通过在组件上添加事件监听器来实现的。事件监听器是一个函数,它会在特定的事件发生时被调用。可以通过以下几个步骤来处理事件逻辑: 在组件类中定义事件处理函数。例如,可以在组件类中定义一个叫做handleClick的事件…

比瓴科技入围软件供应链安全赛道!为关键信息基础设施安全建设注入新动力

1月20日,中关村华安关键信息基础设施安全保护联盟会员大会暨关键信息基础设施安全保护论坛在北京成功举办,比瓴科技作为会员单位受邀出席。 本次论坛发布了《关键信息基础设施安全保护支撑能力白皮书(2023)》,比瓴科技…

蓝桥杯客观题练习笔记

1、蓝桥杯单片机开发板供电为几V? 5V DS18B20是单工通讯,还是半双工通讯?为什么? 将时钟线,数据线,控制线和电源线合并为一根线,只要符合单总线协议的器件都能以从机的身份挂接到单总线上与主…

【开源】SpringBoot框架开发大学计算机课程管理平台

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 实验课程档案模块2.2 实验资源模块2.3 学生实验模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 实验课程档案表3.2.2 实验资源表3.2.3 学生实验表 四、系统展示五、核心代码5.1 一键生成实验5.2 提交实验5.3 批阅实…

许昌路280号3号办公楼室内精装修项目

许昌路280号3号办公楼室内精装修项目 (招标编号:2024-上水管线-201) 项目所在地区:上海市 一、招标条件 本许昌路280号3号办公楼室内精装修项目已由项目审批/核准/备案机关批准,项目资金来源为国有资金0万元:私有资金0万元;境外资金0万元;自筹资金480万元;外国政府及…

获取真实 IP 地址(二):绕过 CDN(附链接)

一、DNS历史解析记录 DNS 历史解析记录指的是一个域名在过去的某个时间点上的DNS解析信息记录。这些记录包含了该域名过去使用的IP地址、MX记录(邮件服务器)、CNAME记录(别名记录)等 DNS 信息。DNS 历史记录对于网络管理员、安全研…

架构师为什么要写文档?又该如何写文档呢?

大家好,我是冰河~~ 最近有很多小伙伴,也不乏身边的一些同事问我:哎,架构师为什么要写这么多文档啊?有啥用呢?不能跟开发一样多写写代码吗?天天写文档,又感觉自己的文档写不好&#…

2023年12月CCF-GESP编程能力等级认证Python编程五级真题解析

Python等级认证GESP(1~6级)全部真题・点这里 一、单选题(共15题,共30分) 第1题 通讯卫星在通信网络系统中主要起到( )的作用。 A:信息过滤 B:信号中继 C:避免攻击 D:数据加密 答案:B 第2题 小杨想编写一个判断任意输入的整数N是否为素数的程序,下面哪个方法…

怪物联萌小游戏

欢迎来到程序小院 怪物联萌 玩法:将怪物连体,怪物只能直线上下左右移动,躲过障碍物,共16关卡, 不同关卡不同界面,遇到金币记得吃掉金币哦,会获得更高分数,快去闯关吧^^。开始游戏ht…

纯血鸿蒙来了,鸿蒙App开发该如何提速

“全世界做产品挣钱的公司很多,但有能力打造操作系统的公司没有几家,最后世界上的操作系统就只有三套:鸿蒙、iOS和安卓。” --- 360集团创始人、董事长周鸿祎 “HarmonyOS实现了AI框架、大模型、设计系统、编程框架、编程语言、编译器等全栈…

git的分支操作

目录 简介: 操作:查看 操作:创建 操作:切换​编辑 操作:本地分支推送到远程 操作:git merge [name]合并分支​编辑 简介: 在Git中,可以通过分支来管理和处理不同的版本和功能。分…

一文读懂C++的类和对象以及多态的原理

现实生活中,关于类和对象最好的例子是自然界的动物类,本文将以此为场景逐步引入C的概念,达到学习的目的。因为C这门语言本身有很多繁杂的内容,而网上的资源也是参差不齐,有的人见山谈山遇水聊水,有多人故弄…