redis和数据库的数据一致性

news2024/11/24 13:45:12

在我们使用redis作为缓存的时候,数据库和缓存数据保持一致性就显得尤为重要,因为如果不做处理的话很有可能读取到的数据会出现差错,那这里怎么进行解决呢?

首先我们先来看一下操作数据到底是直接删除数据还是说通过修改的方式来修改数据呢?

如果是直接删除的话,那当然我们直接删除缓存的数据就行了,但是如果是更新 Redis 中的数据,可能会涉及到一系列复杂的业务逻辑计算,整个更新操作所需要付出的成本是比删除操作更高的,所以我们会选择直接删除数据。

那删除数据时先删缓存呢还是先删数据库中的数据呢?

先删缓存,再删数据库

我们先来看看先删缓存中的数据会出现什么问题:

整个步骤已经在图中进行标明,这里还是大概说一下步骤:

线程1去操作数据,先去缓存中删除数据,然后去数据库中进行更新,但是这个时候出现了网络延迟或其他问题,导致数据库的数据还没更新成功,线程2就开始从redis中进行读取数据;

线程2发现redis中没有这条数据,所以就去数据库中读,但是此时数据库中的数据依然是没有更新的数据,所以读取到的数据还是老数据,然后同步到redis当中;

这个时候线程1才将数据修改到数据库中,但是对于之后的线程读取的数据依旧是redis中的老数据,只有等到redis的缓存过期之后,才会从数据库读到新的数据。

解决办法

延时双删

既然是因为缓存的原因,那我可不可以把缓存中的数据再删一次,然后去数据库里面读取新数据呢?这个想法是没毛病滴~

当线程2从数据库读取到数据之后,再把数据同步到redis当中,这个时候我们就需要做一个删除的操作,但是这个延迟删除的时间需要是等到线程1把数据同步到数据库中后,才进行删除,不然读到的还是旧数据,这个延时的时间需要你根据业务的整个执行时间去判断大概需要延时到多少~

当然,这个解决方法的话还是会出现部分请求到的数据依旧是老数据,但是最终结果上是解决了数据不一致的问题~

最终一致性和强一致性

所以这里还提供了一种方法,使用最终一致性和强一致性,这种就可以解决我们前几次还是会出现缓存不一致的问题。

你可以想想,因为redis和数据库都是分布在不同的机器上分别进行处理的,即使是在同一台机器上执行也是需要两步操作才能完成,所以如果我们要保证操作缓存和操作数据库的原子性,就需要对他进行加锁。

但是我们加锁了肯定是会影响吞吐量的,但是我们设置缓存的目的就是减少系统吞吐量,这样一来加锁之后肯定会对系统性能造成影响,所以为了保证系统性能,我们还是不建议使用这种做法~

还留有另外一种操作数据的方法

先删数据库,再删缓存(推荐)

这张图也给出了一个大概步骤,我这里再梳理一下流程:

线程1操作数据,先去数据库中删除数据,然后再更新到混存当中,然后线程2从缓存中读取数据并返回。

但是这里会存在问题,你可以想一想,如果我的线程1在删除数据库数据的时候,因为网络延迟或者某些原因,还没有执行完成,这个时候缓存数据过期,线程2只能从数据库中获取数据,但是获取到的数据依旧是旧数据,然后线程1将数据库修改成功后再去删除缓存,然后线程2再把数据同步到缓存中,那这个时候缓存中的数据依旧是旧数据,从而导致数据一致性被破坏。

如果我数据库布置的是集群,那么主数据库写数据,从数据库读数据,如果这个时候我对主数据库写完数据后,从数据库还没来得及更新,那么其它线程来请求数据的时候,在从数据里面读取到的数据就是还未更新的数据,那么数据一致性也会被破坏掉~

解决办法

删除+延迟双删

和上一个提到的延迟双删一样,先删除一次缓存,然后再做一次延迟双删,当然什么时候做延迟双删的操作还是需要根据业务中的整个时间来进行判断,得等到我数据库修改完成再删除缓存后,再进行删除。

当然,频繁的删除操作对缓存是不友好的,很容易出现缓存击穿的问题~

删除失败怎么办

如果我们在删除缓存的时候删除失败了怎么办,就拿我们先更新数据库,在删缓存的场景来讲,我们可以借助消息队列设置一个重试机制,在重试达到我们设置的值之后,还是没能删除成功的话,我们可以把这个删除失败的消息通过消息中间件把消息返回给线程1,并发送告警给相关人员,从而人工介入~

如果是在高并发的情况下出现的这种情况,我们建议使用异步的方式来实现消息发送~

当然,使用这种方式的话,整个代码的耦合性还是很高的,如果想要降低耦合,我们可以引入一个组件——canal,但是引入组件后,整个系统的复杂性就会增加,这里就不多说了,感兴趣的小伙伴可以再深入了解一下~

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

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

相关文章

发布 VectorTraits v3.0(支持 X86架构的Avx512系列指令集,支持 Wasm架构及PackedSimd指令集等)

文章目录 支持 X86架构的Avx512系列指令集支持Avx512时的输出信息 支持 Wasm架构及PackedSimd指令集支持PackedSimd时的输出信息VectorTraits.Benchmarks.Wasm 使用说明 新增了向量方法支持 .NET 8.0 新增的向量方法提供交织与解交织的向量方法YGroup3Unzip的范例代码 提供重新…

工业相机常用功能之白平衡及C++代码分享

目录 1、白平衡的概念解析 2、相机白平衡参数及操作 2.1 相机白平衡参数 2.2 自动白平衡操作 2.3 手动白平衡操作流程 3、C++ 代码从XML读取参数及设置相机参数 3.1 读取XML 3.2 C++代码,从XML读取参数 3.3 给相机设置参数 1、白平衡的概念解析 白平衡(White Balance)…

推荐一款SSD硬盘优化器:Auslogics SSD Optimizer Pro

SSD Optimizer Pro 是一款专为优化固态硬盘 (SSD) 性能而设计的专业工具,旨在最大化 SSD 的效率,延长硬盘使用寿命。凭借简便的操作界面和强大的优化功能,SSD Optimizer Pro 可以让用户充分利用 SSD 的优势,从而获得更高的系统性能…

常用机器人算法原理介绍

一、引言 随着科技的不断发展,机器人技术在各个领域得到了广泛应用。机器人算法是机器人实现各种功能的核心,它决定了机器人的行为和性能。本文将介绍几种常用的机器人算法原理,包括路径规划算法、定位算法和运动控制算法。 二、路径规划算法…

基于开源 AI 智能名片 S2B2C 商城小程序的视频号交易小程序优化研究

摘要:本文探讨了完善适配视频号交易小程序的重要意义,重点阐述了开源 AI 智能名片 S2B2C 商城小程序在这一过程中的应用。通过分析其与直播间和社群的无缝衔接特点,以及满足新流量结构下基础设施需求的能力,为门店在视频号直播交易…

【OH】openHarmony开发环境搭建(基于windows子系统WSL)

前言 本文主要介绍基于windows子系统WSL搭建openHarmony开发环境。 WSL与Vmware虚拟机的区别,可以查看WSL与虚拟机的区别 更详细的安装配置过程可参考微软官网: ​安装 WSL 前提 以下基于windows 111专业版进行配置,windows 10应该也是可以…

WPF使用Prism框架首页界面

1. 首先确保已经下载了NuGet包MaterialDesignThemes 2.我们通过包的项目URL可以跳转到Github上查看源码 3.找到首页所在的代码位置 4.将代码复制下来&#xff0c;删除掉自己不需要的东西&#xff0c;最终如下 <materialDesign:DialogHostDialogTheme"Inherit"Ide…

AHB Matrix 四星级 验证笔记(2.4) Tt3.3AHB总线协议测试时的 并行数据

文章目录 前言一、代码二、错误1.地址范围2. 并行执行线程中变量覆盖的情况3.有关incr的beat 前言 来源路科验证本节搞定 T3.3 AHB总线协议的覆盖&#xff1a;AHB_PROTOCOL_COVER 即测试ahb slave接口和master接口支持&#xff08;尽可能&#xff09;全部的ahb协议传输场景&am…

C++builder中的人工智能(16):神经网络中的SoftPlus激活函数

现在我们继续探索一下SoftPlus激活函数在人工神经网络&#xff08;ANN&#xff09;中的应用。了解SoftPlus激活函数的工作原理&#xff0c;将有助于您在使用C IDE构建C应用程序时更加得心应手。 目录 神经网络中的激活函数是什么&#xff1f;能在C中创建激活函数吗&#xff1f…

Java的(.properties后缀)的配置文件介绍与读取(3种情况)

目录 一、&#xff08;.properties后缀&#xff09;的配置文件。 &#xff08;1&#xff09;基本介绍。 &#xff08;2&#xff09;基本语法。 1、键值对。 2、如何注释&#xff1f; 3、编码类型。 4、空白字符。 5、多行值。 &#xff08;3&#xff09;".properties后缀&…

yaml文件编写

Kubernetes 支持YAML和JSON格式管理资源 JSON 格式:主要用于 api 接口之间消息的传递 YAML 格式;用于配置和管理,YAML是一种简洁的非标记性语言,内容格式人性化容易读懂 一&#xff0c;yaml语法格式 1.1 基本语法规则 使用空格进行缩进&#xff08;不使用制表符&#xff0…

Node.js——fs模块-文件删除

1、在Node.js中&#xff0c;我们可以使用unlink或unlinkSync来删除文件。 2、语法&#xff1a; fs.unlink(path,callback) fs.unlinkSync(path) 参数说明&#xff1a; path 文件路径 callback 操作后的回调函数 本文的分享到此结束&#xff0c;欢迎大家评论区一同讨论学…

新版IJidea 如何打开数据库窗口(2024.2.4 版)(连接数据库)

新版IJidea 2024.2.4 如何打开数据库窗口&#xff1f; 方式&#xff1a;使用插件&#xff0c;Database Navigator 1.安装插件&#xff0c;步骤如下&#xff1a; 打开 Settings/Preferences 对话框&#xff08;快捷键 CtrlAltS&#xff09;。前往 Plugins 菜单项。在搜索框中…

黄仁勋:AI数据中心可扩展至百万芯片 性能年翻倍,能耗年减2-3倍

本周&#xff0c;英伟达CEO黄仁勋接受了《No Priors》节目主持人的采访&#xff0c;就英伟达的十年赌注、x.AI超级集群的快速发展、NVLink技术创新等AI相关话题进行了一场深度对话。黄仁勋表示&#xff0c;没有任何物理定律可以阻止将AI数据中心扩展到一百万个芯片&#xff0c;…

java 面向对象高级

1.final关键字 class Demo{public static void main(String[] args) {final int[] anew int[]{1,2,3};// anew int[]{4,5,6}; 报错a[0]5;//可以&#xff0c;解释了final修饰引用性变量&#xff0c;变量存储的地址不能被改变&#xff0c;但地址所指向的对象的内容可以改变} }什…

Codeforces Round 984 (Div. 3)

题目链接 A. Quintomania 题意 思路 模拟即可 示例代码 void solve() {int n;cin >> n;vector<int>arr(n);fer(i, 0 ,n) cin >> arr[i];fer(i, 1, n){if(abs(arr[i] - arr[i - 1]) ! 5 && abs(arr[i] - arr[i - 1]) ! 7){cout << "N…

基于BILSTM及其他RNN序列模型的人名分类器

数据集Kaggle链接 NameNationalLanguage | Kaggle 数据集分布: 第一列为人名,第二列为国家标签 代码开源地址 Kaggle代码链接 https://www.kaggle.com/code/houjijin/name-nationality-classification Gitee码云链接 人名国籍分类 Name Nation classification: using BI…

打包18款AI营销神器,批量运营项目收藏必备!

淘金的不如卖铲子的&#xff0c;AI工具的应用越来越普及&#xff0c;这也让很多原本淘金的人都来卖铲子。如果自己能有很好的铲子&#xff0c;自己也会淘金&#xff0c;就可以既能卖铲子赚钱&#xff0c;也能掏金赚钱。 还有两天就是双十一了&#xff0c;各种AI工具&#xff0…

Leetcode - 周赛422

目录 一&#xff0c;3340. 检查平衡字符串 二&#xff0c;3341. 到达最后一个房间的最少时间 I 三&#xff0c;3342. 到达最后一个房间的最少时间 II 四&#xff0c;3343. 统计平衡排列的数目 一&#xff0c;3340. 检查平衡字符串 本题直接暴力&#xff0c;定义一个变量 s&…

聚观早报 | 比亚迪腾势D9登陆泰国;苹果 iOS 18.2 将发布

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 11月5日消息 比亚迪腾势D9登陆泰国 苹果 iOS 18.2 将发布 真我GT7 Pro防尘防水细节 小米15 Ultra最快明年登场 …