Redis与MySQL如何保证数据一致性

news2024/11/27 8:20:49

Redis与MySQL如何保证数据一致性

简单来说

该场景主要发生在读写并发进行时,才会发生数据不一致。

主要流程就是要么先操作缓存,要么先操作Redis,操作也分修改和删除。

一般修改要执行一系列业务代码,所以一般直接删除成本较低。

如果我们先删除Redis中数据,就会出现修改数据库数据时,其他线程读取到Redis为空,从数据库查,并写入Redis中,但这就是脏数据了,所以可以采用延迟双删策略,就是再删除一次,需要延迟的原因是因为在其他线程查时给Redis设置旧数据时,不延迟,就会覆盖新数据。(所以一般都要根据自己的业务逻辑评估一下大概时间。)如果说需要在这个阶段也需要保证数据一致性,那就只能上锁,保证强一致性,因为Redis和数据库是两个服务,只能通过加锁保证原子性,而这就影响了系统吞吐量(就违背了使用Redis提高吞吐量,也就是AP和CP不能同时满足的问题),所以一般都是保证最终一致性。

如果先修改数据库,同样会有数据不一致情况,在修改数据库处理时,其他线程也会读取旧数据,处理完了数据库就会删除缓存,保证了数据最终一致性,(所以比较推荐这种操作)

但是上述两种都会有删除Redis失败的情况,可以选择异步发送消息到MQ,线程监听MQ执行重试删除。

但这里的MQ代码过于耦合,需要解耦的话,就可以将他们提取出来,使用阿里的一款开源框架canal主要用途是基于MySQL数据库增量日志解析,提供增量数据订阅和消费Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端,过程也就是执行失败后,异步发送消息到MQ,Canal客户端监听到MQ消息执行重试

 

详细来说

1、引入

Redis 用来实现应用和数据库之间读操作的缓存层,主要目的是减少数据库 IO,还可以提升数据的 IO 性能。

当应用程序需要去读取某个数据的时候,首先会先尝试去 Redis 里面加载,如果命中就直接返回。如果没有命中,就从数据库查询,查询到数据后再把这个数据缓存到 Redis 里面。

这样一个架构中,会出现一个问题,就是一份数据,同时保存在数据库和 Redis 里面,当数据发生变化的时候,需要同时更新 Redis 和 Mysql,由于更新是有先后顺序的,并且它不像 Mysql中的多表事务操作,可以满足 ACID 特性。所以就会出现数据一致性问题。

e27e36563ec144118801ddf5724ebd46.png

 

2、同步策略

想要保证缓存与数据库的双写一致,一共有4种方式,即4种同步策略:

先更新缓存,再更新数据库; 先更新数据库,再更新缓存; 先删除缓存,再更新数据库; 先更新数据库,再删除缓存。 从这4种同步策略中,我们需要作出比较的是:

更新缓存与删除缓存哪种方式更合适?应该先操作数据库还是先操作缓存?

一般直接删除,因为缓存的更新成本更高 (因为你写入数据库的值,很多情况并不是直接写入缓存的,而是要经过一系列复杂的计算再写入缓存。那么,每次写入数据库后,都再次计算写入缓存的值无疑是浪费性能的。显然,删除缓存更为适合。)删除缓存操作简单,副作用只是增加了一次 chache miss,建议大家使用该策略。

一般先操作数据库,因为更方便保证最终一致性,先往下看

 

3、操作理解

先操作缓存

3f428d8e9f084cea8af330909520c273.png

如果我们先删除Redis中数据,就会出现修改数据库数据时,其他线程读取到Redis为空,从数据库查,并写入Redis中,但这就是脏数据了,所以可以采用延迟双删策略,就是再删除一次,需要延迟的原因是因为在其他线程查时给Redis设置旧数据时,不延迟,就会覆盖新数据。(所以一般都要根据自己的业务逻辑评估一下大概时间。)如果说需要在这个阶段也需要保证数据一致性,那就只能上锁,保证强一致性,因为Redis和数据库是两个服务,只能通过加锁保证原子性,而这就影响了系统吞吐量(就违背了使用Redis提高吞吐量,也就是AP和CP不能同时满足的问题),所以一般都是保证最终一致性。

 

先操作数据库

2ed9f84a85764e61999bf3cdb820b72a.png

 

如果先修改数据库,同样会有数据不一致情况,在修改数据库处理时,其他线程也会读取旧数据,处理完了数据库就会删除缓存,保证了数据最终一致性,(所以比较推荐这种操作)

 

4、解决

一般使用延迟双删和删除重试机制

延迟双删

一个读线程发现缓存中没有对应的数据,去查库,在查询完毕准备更新缓存期间,另一个写线程完成了写库以及对缓存的删除此时数据库中的数据是新数据,而读线程将缓存更新为旧数据),一般情况下,这种事件的发生概率很低,但是使用延迟双删可以规避掉这种问题,进一步提高数据的一致性,但缺点就是性能会有所下降

那具体的超时时间要根据你具体的业务来定,一般设置几秒足够了

队列+重试机制

上述情况都会有删除Redis失败的情况,可以使用重试机制

比如重试三次,三次都失败则记录日志到数据库并发送警告让人工介入在高并发的场景下,重试最好使用异步方式,比如发送消息到 mq 中间件,实现异步解耦

也就是选择异步发送消息到MQ,线程监听MQ执行重试删除。

 

62bd2f223be64a768574793d5e4feb1c.png

Cannal解耦

但这里的MQ代码过于耦合,需要解耦的话,就可以将他们提取出来,使用阿里的一款开源框架canal主要用途是基于MySQL数据库增量日志解析,提供增量数据订阅和消费Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端,过程也就是执行失败后,异步发送消息到MQ,Canal客户端监听到MQ消息执行重试

通过该框架可以对MySQL的binlog进行订阅,而canal正是模仿了mysql的slave数据库的备份请求,使得Redis的数据更新达到了相同的效果。 MQ消息中间可以采用RocketMQ来实现推送

 

3b04924a27fc454fbc99cc0906f248b4.png

 

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

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

相关文章

Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)

目录 一、前言 二、技术介绍 三、系统实现 四、核心代码 五、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者,专注于大学生项目实战开发、讲解和毕业答疑辅导 一、前言 在充满活力与激情的校园生活中,校运会不仅是…

【西瓜书】神经网络-MP神经元、感知机和多层网络

神经网络(neural networks)的定义:神经网络是由具有适应性的简单单元组成的广泛并行互联的网络,它的组织能够模拟生物神经系统对真实世界物体所作出的交互反应。(T. Kohonen 1988年在Neural Networks创刊号上给出的定义…

《安富莱嵌入式周报》第346期:开源2GHz带宽,12bit分辨率,3.2Gsps采样率示波,开源固件安全分析器, 开源口袋电源,开源健康测量,FreeCAD

周报汇总地址:嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频: https://www.bilibili.com/video/BV1TYBhYKECK/ 《安富莱嵌入式周报》第346期:开源2GHz带…

介绍一下atoi(arr);(c基础)

hi , I am 36 适合对象c语言初学者 atoi(arr)&#xff1b;是返回整数(int型)&#xff0c;整数是arr数组中字符中数字 格式 #include<stdio.h> atoi(arr); 返回值arr数组中的数字 未改变arr数组 #include<stdlib.h>//atoi(arr); 返 <stdlib> int main(…

Docker: 教程07 - ( 如何对 Docker 进行降级和升级)

如果我们使用 docker 来管理容器&#xff0c;那么保持 docker 引擎的更新将会是十分重要的&#xff0c;这一篇文章我们将会讨论如何对Docker 进行降级和升级。 准备工作 - docker 环境 我们需要拥有一个安装好 docker 的运行环境。 如果你需要了解如何安装 docker 可以通过如…

ArcGIS pro中的回归分析浅析(加更)关于广义线性回归工具的补充内容

在回归分析浅析中篇的文章中&#xff0c; 有人问了一个问题&#xff1a; 案例里的calls数据貌似离散&#xff0c;更符合泊松模型&#xff0c;为啥不采用泊松而采用高斯呢&#xff1f; 确实&#xff0c;在中篇中写道&#xff1a; 在这个例子中我们为了更好地解释变量&#x…

第R4周:LSTM-火灾温度预测(TensorFlow版)

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营]中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊]** 往期文章可查阅&#xff1a; 深度学习总结 任务说明&#xff1a;数据集中提供了火灾温度&#xff08;Tem1&#xff09;、一氧化碳浓度…

《操作系统 - 清华大学》5 -4:虚拟技术

文章目录 0. 虚拟存储的定义1. 目标2.局部性原理3. 虚拟存储的思路与规则4. 虚拟存储的基本特征5. 虚拟页式存储管理5.1 页表表项5.2 示例 0. 虚拟存储的定义 1. 目标 虚拟内存管理技术&#xff0c;简称虚存技术。那为什么要虚存技术&#xff1f;在于前面覆盖和交换技术&#…

MYSQL 表的增删改查(上)

目录 1.新增数据 2.查询数据 一般查询 去重查询 排序查询 关于NULL 条件查询 分页查询 1.新增数据 语法&#xff1a;insert into 表名[(字段1&#xff0c;字段2...)] values (值&#xff0c;值....); 插入一条新数据行&#xff0c;前面指定的列&#xff0c;要与后面v…

OSPTrack:一个包含多个生态系统中软件包执行时生成的静态和动态特征的标记数据集,用于识别开源软件中的恶意行为。

2024-11-22 &#xff0c;由格拉斯哥大学创建的OSPTrack数据集&#xff0c;目的是通过捕获在隔离环境中执行包和库时生成的特征&#xff0c;包括静态和动态特征&#xff0c;来识别开源软件&#xff08;OSS&#xff09;中的恶意指标&#xff0c;特别是在源代码访问受限时&#xf…

[Docker-显示所有容器IP] 显示docker-compose.yml中所有容器IP的方法

本文由Markdown语法编辑器编辑完成。 1. 需求背景: 最近在启动一个服务时&#xff0c;突然发现它的一个接口&#xff0c;被另一个服务ip频繁的请求。 按理说&#xff0c;之前设置的是&#xff0c;每隔1分钟请求一次接口。但从日志来看&#xff0c;则是1秒钟请求一次&#xff…

如何寻找适合的HTTP代理IP资源?

一、怎么找代理IP资源&#xff1f; 在选择代理IP资源的时候&#xff0c;很多小伙伴往往将可用率作为首要的参考指标。事实上&#xff0c;市面上的住宅IP或拨号VPS代理IP资源&#xff0c;其可用率普遍在95%以上&#xff0c;因此IP可用率并不是唯一的评判标准 其实更应该关注的…

idea_卸载与安装

卸载与安装 卸载1、设置 -> 应用2、查找到应用&#xff0c;点击卸载3、把删除记录和设置都勾选上4、删除其它几个位置的残留 安装1、下载安装包2、欢迎安装 -> Next3、选择安装目录 -> Next4、创建快捷图标和添加到环境变量5、确认文件夹的名称 -> Install6、完成安…

【Axure高保真原型】天气模板

今天和大家分享天气模板的原型模板&#xff0c;里面包括晴天、多云、阴天、小雨、大雨、暴雨、强雷阵雨、小雪、中雪、大雪、暴雪、雨夹雪、微风、强风、狂风、龙卷风、轻雾、大雾等&#xff0c;后续也可以自行添加。 这个模板是用中继器制作的&#xff0c;所以使用也很方便&a…

深度学习模型:循环神经网络(RNN)

一、引言 在深度学习的浩瀚海洋里&#xff0c;循环神经网络&#xff08;RNN&#xff09;宛如一颗独特的明珠&#xff0c;专门用于剖析序列数据&#xff0c;如文本、语音、时间序列等。无论是预测股票走势&#xff0c;还是理解自然语言&#xff0c;RNN 都发挥着举足轻重的作用。…

Prometheus告警带图完美解决方案

需求背景 告警分析处理流程 通常我们收到 Prometheus 告警事件通知后&#xff0c;往往都需要登录 Alertmanager 页面查看当前激活的告警&#xff0c;如果需要分析告警历史数据信息&#xff0c;还需要登录 Prometheus 页面的在 Alerts 中查询告警 promQL 表达式&#xff0c;然…

深入理解 Java 基本语法之运算符

&#xff08;一&#xff09;研究背景 在 Java 编程中&#xff0c;运算符是处理数据和变量的基本工具&#xff0c;掌握各种运算符的使用方法对于提高编程效率至关重要。 &#xff08;二&#xff09;研究目的 深入理解 Java 基础运算符的概念、分类和作用&#xff0c;通过具体…

iOS 17.4 Not Installed

0x00 系统警告 没有安装 17.4 的模拟器&#xff0c;任何操作都无法进行&#xff01; 点击 OK 去下载&#xff0c;完成之后&#xff0c;依旧是原样&#xff01; 0x01 解决办法 1、先去官网下载对应的模拟器&#xff1a; https://developer.apple.com/download/all/?q17.4 …

Flink细粒度的资源管理

Apache Flink致力于为所有应用程序自动导出合理的默认资源需求。对于希望根据其特定场景微调其资源消耗的用户,Flink提供了细粒度的资源管理。这里我们就来看下细粒度的资源管理如何使用。(注意该功能目前仅对DataStream API有用) 1. 适用场景 使用细粒度的资源管理的可能…