Redis和MySQL如何保持数据一致性

前言

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

1.数据不一致的原因

1.1导致数据不一致的原因

  • 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。

  • 所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库。

  • 读取缓存步骤一般没有什么问题,但是一旦涉及到数据更新:数据库和缓存更新,就容易出现缓存(Redis)和数据库(MySQL)间的数据一致性问题。

  • 这个业务场景,主要是解决读数据从Redis缓存,一般都是按照下图的流程来进行业务操作。

图片

1.2 缓存先后删除问题

不管是先写MySQL数据库,再删除Redis缓存;还是先删除缓存,再写库,都有可能出现数据不一致的情况。

2.1 先删除缓存

  • 如果先删除Redis缓存数据,然而还没有来得及写入MySQL,另一个线程就来读取

  • 这个时候发现缓存为空,则去Mysql数据库中读取旧数据写入缓存,此时缓存中为脏数据。

  • 然后数据库更新后发现Redis和Mysql出现了数据不一致的问题

2.2 后删除缓存

  • 如果先写了库,然后再删除缓存,不幸的写库的线程挂了,导致了缓存没有删除

  • 这个时候就会直接读取旧缓存,最终也导致了数据不一致情况

  • 因为写和读是并发的,没法保证顺序,就会出现缓存和数据库的数据不一致的问题

2.解决方案

2.1 延时双删策略

2.1.1 基本思路

  • 在写库前后都进行redis.del(key)操作,并且设定合理的超时时间。

  • 伪代码如下:

public void write( String key, Object data ){

redis.delKey( key );

db.updateData( data ); 

Thread.sleep( 500 ); r

edis.delKey( key );

}

2.1.2 具体步骤

  • 1.先删除缓存

  • 2.再写数据库

  • 3.休眠500毫秒

  • 4.再次删除缓存

问题:这个500毫秒怎么确定的,具体该休眠多久时间呢?

  • 需要评估自己的项目的读数据业务逻辑的耗时。

  • 这么做的目的,就是确保读请求结束,写请求可以删除读请求造成的缓存脏数据。

  • 当然这种策略还要考虑redis和数据库主从同步的耗时。

  • 最后的写数据的休眠时间:则在读数据业务逻辑的耗时基础上,加几百ms即可。比如:休眠1秒。

2.1.3 设置缓存过期时间是关键点

  • 从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案

  • 所有的写操作以数据库为准,只要到达缓存过期时间,缓存删除

  • 如果后面还有读请求的话,就会从数据库中读取新值然后回填缓存

2.1.4 方案缺点

结合双删策略+缓存超时设置,这样最差的情况就是:

  • 在缓存过期时间内发生数据存在不一致

  • 同时又增加了写请求的耗时。

2.2 异步更新缓存(基于Mysql binlog的同步机制)

2.2.1 整体思路

  • 1.涉及到更新的数据操作,利用Mysql binlog 进行增量订阅消费

  • 2.将消息发送到消息队列

  • 3.通过消息队列消费将增量数据更新到Redis上

  • 4.操作情况

  • 读取Redis缓存:热数据都在Redis上

  • 写Mysql:增删改都是在Mysql进行操作

  • 更新Redis数据:Mysql的数据操作都记录到binlog,通过消息队列及时更新到Redis上

2.2.2 Redis更新过程

(1) 数据操作主要分为两种:

  • 一种是全量(将所有数据一次性写入Redis)

  • 一种是增量(实时更新)

这里说的是增量,指的是mysql的update、insert、delate变更数据。

(2)读取binlog后分析 ,利用消息队列,推送更新各台的redis缓存数据。

  • 这样一旦MySQL中产生了新的写入、更新、删除等操作,就可以把binlog相关的消息推送至Redis

  • Redis再根据binlog中的记录,对Redis进行更新

  • 其实这种机制,很类似MySQL的主从备份机制,因为MySQL的主备也是通过binlog来实现的数据一致性

这里的消息推送工具你也可以采用别的第三方:kafka、rabbitMQ等来实现推送更新Redis!

3.总结

在高并发应用场景下,如果是对数据一致性要求高的情况下,要定位好导致数据和缓存不一致的原因。

解决高并发场景下数据一致性的方案有两种,分别是延时双删策略和异步更新缓存两种方案。

另外,设置缓存的过期时间是保证数据保持一致性的关键操作,需要结合业务进行合理的设置。

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

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

相关文章

Pyside6/PyQt6图标设置必备:窗口图标、软件图标、任务栏图标与系统托盘图标设置详解(含示例源码)

文章目录 📖 介绍 📖🏡 环境 🏡📒 图标设置 📒📝 设置窗口图标📝 设置软件/任务栏图标📝 设置系统托盘图标🎈 添加右键菜单/全局快捷键/隐藏任务栏图标⚓️ 相关链接 ⚓️📖 介绍 📖 在创建图形用户界面(GUI)应用程序时,一个吸引人的图标是必不可少…

day10

1.构造代码块和构造方法的区别 {代码块 } public 类名 () {} 都是实例化一个对象的时候执行的 只不过构造代码块先于构造方法执行的 2.局部变量和成员变量区别局部变量写在方法中,只能在方法体中使用,出了这个方法就不能再使用了成…

AI对决:ChatGPT与文心一言的深度比较

. 个人主页:晓风飞 专栏:数据结构|Linux|C语言 路漫漫其修远兮,吾将上下而求索 文章目录 引言ChatGPT与文心一言的比较Chatgpt的看法文心一言的看法Copilot的观点chatgpt4.0的回答 模型的自我评价自我评价 ChatGPT的优势在这里插入图片描述 文…

【刷题】leetcode 1 . 两数之和

两数之和 两数之和1 思路一 (简单突破)2 思路二 (进行优化)3 思路三 (哈希表 我还不会) 谢谢阅读Thanks♪(・ω・)ノ下一篇文章见!!! 两数…

uniapp的nvue是什么

什么是nvue uni-app App 端内置了一个基于 weex 改进的原生渲染引擎,提供了原生渲染能力。 在 App 端,如果使用 vue 页面,则使用 webview 渲染;如果使用 nvue 页面(native vue 的缩写),则使用原生渲染。一个 App 中可…

USB Redirector本地安装并结合内网穿透实现远程共享和访问USB设备

文章目录 前言1. 安装下载软件1.1 内网安装使用USB Redirector1.2 下载安装cpolar内网穿透 2. 完成USB Redirector服务端和客户端映射连接3. 设置固定的公网地址 前言 USB Redirector是一款方便易用的USB设备共享服务应用程序,它提供了共享和访问本地或互联网上的U…

十五.流程控制与游标

流程控制与游标 1.流程控制1.1分支结构之IF1.2分支结构值CASE1.3循环结构之LOOP1.4循环结构之WHILE1.5循环结构之REPEAT1.6跳转语句之LEAVE语句1.7跳转语句之ITERATE语句 2.游标2.1什么是游标2.2使用游标步骤4.3举例4.5小结 1.流程控制 解决复杂问题不可能通过一个 SQL 语句完…

深度学习基础知识整理

自动编码器 Auto-encoders是一种人工神经网络,用于学习未标记数据的有效编码。它由两个部分组成:编码器和解码器。编码器将输入数据转换为一种更紧凑的表示形式,而解码器则将该表示形式转换回原始数据。这种方法可以用于降维,去噪…

【图形学】直线光栅化算法(DDA算法和Bresenham算法)

在数学上,直线就是由无穷多个点组成的, 在计算机屏幕显示的话, 需要做一些处理,对于光栅显示器,就是用有限多个点去逼近直线, 我们需要知道每一个像素点的坐标(都是整数) 数学上直线的方程如下 y k x b ykxb ykxb,给定直线的起点坐标 P 0 ( x 0 , y…

开源 UI 组件库和开发工具库概览 | 开源专题 No.59

ant-design/ant-design Stars: 87.9k License: MIT Ant Design 是一个企业级 UI 设计语言和 React UI 库。 为 Web 应用程序设计的企业级 UI。提供一套高质量的开箱即用的 React 组件。使用可预测静态类型编写 TypeScript 代码。包含完整的设计资源和开发工具包。支持数十种语…

QT上位机开发(软件的发布和部署)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 我们在读书的时候,如果程序写好了,这个时候一般直接把exe拷贝给老师就可以了。这就是最原始的软件发布。但是,这…

“核弹级“攻击队视角下的监管痛点解决方案

痛点分析及解决方案 一、辖区企业资产分散且不透明 - 传统的监管体系中,政府监管单位往往面临着辖区企业资产分散且不透明的问题。 - 企业无法梳理自身资产,上报的资产台账无法涵盖全部自身资产 - 监管单位精力有限,无法保证辖区企业资产台账…

解决jmeter测试计划无法保存、另存为的问题

问题: 在保存测试计划时直接保存在C:\Windows\System32, 导致执行时报错Couldn’t save test plan to file:C:\Windows\System32 解决方案: 将路径改为 options--------Look And Feel-------windows

Express框架使用全流程

1.目的和使用场景 对于像我这样不常使用 Node.js 进行开发的人来说,每次开始一个新项目都意味着从头开始设置环境,这个过程相当繁琐。因此,我决定自己构建一个开箱即用的项目脚手架。我的目标是创建一个简单易用的基础框架,能让我…

NET Core发布 HTTP Error 500.31 - Failed to load ASP.NET Core runtime

记录一下踩过的坑: 首先,不论是500.31还是500.30 ,首先确保安装了三个文件 1.NET Core RunTime 2.NET SDK 3.NET Hosting 其次,确保三个文件的版本一致,如下: 要装就统一装同一个大版本,不要东…

51单片机学习总结(自学)

1、模块化编程 c语言模块化编程实现思路设计代码 具体的程序实现代码如下所示 1:程序的头文件 2:程序的函数文件 3:程序的主文件控制函数的实现 持续更新中......

训练YOLOS-S

文章目录 1 数据处理2 配置训练参数3 可能会遇到的报错 1 数据处理 修改类别数:在models/detector.py中定位到def build(args):,将num_classes进行修改,改为最大的类别id1。我有4个类别,类别id是从0~3,因此max_id3&am…

怎样才能找到合适的产品说明书模板 方法献上

制作一份专业而吸引人的产品手册对于企业来说至关重要。然而,对于许多企业和个人而言,制作产品手册可能是一个挑战,因为需要一定的设计和排版能力。为了帮助大家更轻松地制作出优质的产品手册,下面将向大家推荐三款优秀的产品手册…

如何提高客户消息的快速准确回复能力?

无论是企业还是个人,能够快速而准确地回复客户消息是非常重要的,这不仅可以增强客户对你的信任度,还能促进客户的满意度。 那么,我们该如何提高自己的回复能力呢?接着往下看,你就知道啦! 1、学…

华为埋头造车,躺赚的却是黄牛?

文 | AUTO芯球 作者 | 雷歌 华为和赛力斯正在重庆哼哧a哼哧建厂造车,黄牛却在网上倒卖订单躺着赚钱。 前两天雷歌刚去试驾了问界M9,现场一车难求。 今天回来一看,好家伙,咸鱼上,黄牛们大量倒卖M9的大定订单&#x…
最新文章