彻底理解如何保证Redis和数据库数据一致性问题

一.背景

系统中缓存最常用的策略是:服务端需要同时维护 DB 和 Cache 并且是以 DB 的结果为准,那么就可能出现 DB 和 Cache 数据不一致的问题。

二.读数据

逻辑如下:

当客户端发起查询数据的请求,首先回去Redis中查看没有没该数据,有就返回,没有的话就需要去数据库中查询该数据,并且将该数据缓存在Redis中,然后设置一个过期时间(过期时间的作用就是为了保证一些冷数据能及时被清理,不长时间保存在Redis中,占用Redis的空间),保证在Redis后,返回数据到客户端,这是最常见的一个数据读取场景。

如果我们只读的话,肯定不会出现数据不一致问题,一般是读和写并发的时候才会出现数据不一致问题

三.写数据

分如下两种方式:

更新缓存再更新数据库,还是,先删除缓存再更新数据库;

更新数据库再更新缓存,还是,先更新数据库再删除缓存。

1.删除缓存还是更新缓存?

答:删除!这是因为更新操作相对来说更为复杂,涉及到数据的一致性和同步性等问题;而删除操作相对简单,只需要将缓存中的对应键值对删除即可;在实际的缓存场景中,我们经常会遇到数据更新的频繁性和数据量的大规模,如果每次更新操作都需要同步更新缓存,那么会增加系统的复杂性和开销,而采用只删不更新的方式,可以避免这些问题,当数据被修改时,我们只需要删除缓存中的对应键值对,下一次访问时再重新从数据库或其他数据源中获取最新的数据,并将其存储到缓存中,这种方式可以减少数据同步的开销,并且保证缓存数据的一致性。

2.先操作数据库还是缓存?

(1)先操作缓存

写的场景:先把Redis的数据删除,然后再写入数据库

读写并发场景,如何导致数据不一致:

1)线程1发起修改操作,然后删除Redis中的缓存,此时网络出现卡顿;

2)线程2由于是并发进来,他执行的是一个查询的请求,他会去Redis中查数据,查不到数据,所以会去数据库中查询,此时它查询的是老数据,并且会把数据缓存到Redis中;

3)线程1网络卡顿结束,并把最新数据更新到数据库中;

4)此时数据库是新数据,Redis是老数据,后面再有线程查询请求,请求到的都是老数据,必须等到老数据的过期时间到了,才能重新查询数据库获取到新数据,这个过程之间,一直都会数据不一致。 

解决方案:

线程1把数据库修改成新的后,再执行一遍删除Redis缓存操作,但是线程2查询到的肯定是老数据,所以只会出现数据的一次不一致

那能不能保证不一致一次都不出现?

这就需要引入强一致性概念,如果数据库和Redis是强一致性的话,就必须要保证他们的操作是原子性,因为我们的Redis和数据库是在不同服务器上的,如果要保证他们的操作原子性,就需要去上一把锁,但是加锁后会影响系统的性能,然而我们用Redis就是为了提高系统性能,此时又为了保证强一致性,又去加锁,这样就得不偿失了,所以说,强一致性和性能我们只能保证一种,AP和CP只能保证一种,我们在AP的基础上,就可以采用双删方式保证数据的一致性,虽然会出现一次数据不一致,但是Redis和数据库他们最终的数据都是最新的,所以我们要保存数据一致性的时候会采用这种最终一致性

双删的时候为什么要采用延迟删除?

如果不进行延迟删除,在线程1删除数据后,此时线程2才把老数据放入Redis中,此时的删除相当于没删,同样会出现数据不一致问题,所以需要采用延迟双删方式

延时双删过程:

1)先删除缓存;

2)写数据库;

3)休眠500毫秒,在删除缓存;

这样子最多其他线程在这500毫秒获取到脏数据,这是无法避免的,这个500毫秒不是固定的,需要结合项目的具体业务进行判定(线程2查数据库到放数据到Redis的时间来判定)。

(2)先操作数据库

 写的场景:先写入数据库,然后再把Redis的数据删除

读写并发场景,如何导致数据不一致:

1)线程1发起修改操作,写入数据到数据库,数据库为最新数据;

2)线程2同时并发进来,进行一个查询操作,查询到时老数据,直接返回;

3)线程1然后把Redis的老数据删除,其他线程在进来,查询Redis没有,就会直接查询数据库,并缓存最新数据到Redis。

这样操作下来,也能保证数据的最终一致性,所以推荐先操作数据库,再删除缓存,只是在操作数据库时,其他线程在这个过程中查询的是脏数据。

但是这个操作是否还有问题?

有!比如说数据库插入了最新数据后,删除缓存失败,后续线程进来查询都是老数据,也是需要等待Redis缓存时间过期才能查询到最新的,虽然这是比较极端的情况,但是还是有可能出现,针对删除失败的情况,我们可以采用删除缓存重试机制

可以在删除缓存失败后,异步发送需要删除的Key到MQ中,然后监听MQ,进行重试删除, 如果在设定的重新次数后,还是删除失败,就需要记录日志,让开发人员进行排查问题。

但是重试操作带来的后果就是加入MQ,所以逻辑都放在业务代码中,增加了代码的耦合性,那么要想解耦,可以使用另外一个组件Canal。

(3)Canal解耦

Canal是阿里的一款开源框架,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据订阅和消费,Canal提供了各种语言的客户端,当Canal监听到binlog变化时,会通知Canal的客户端,如下图:

我们可以利用Canal提供的Java客户端,监听Canal通知消息,当收到变化的消息时,完成对缓存的更新。

不管前面先删除缓存,还是先写数据库,最终在数据进行修改的时候,canal会从订阅到binlog日志中将变更的消息通知到canal客户端(Springboot应用),然后进行删除操作,如果删除失败,发送消息到MQ,进行重复删除,这些操作都是在canal客户端进行的,从而个根业务代码进行了解耦。

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

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

相关文章

openwebui使用

文章目录 1、feature2、安装使用2.1 安装过程2.2 安装好后 1、feature 可以加载多个大模型 同时回复 模型问答: 使用vLLM框架部署模型,再使用Open WebUI直接进行模型问答 多模型支持: 多模型回复比对(Qwen2-72B-Instruct, llama3-70b-8192, mixtral-8x7…

.net 8使用hangfire实现库存同步任务

C# 使用HangFire 第一章:.net Framework 4.6 WebAPI 使用Hangfire 第二章:net 8使用hangfire实现库存同步任务 文章目录 C# 使用HangFire前言项目源码一、项目架构二、项目服务介绍HangFire服务结构解析HangfireCollectionExtensions 类ModelHangfireSettingsHttpAuthInfoUs…

【已解决】“EndNote could not connect to the online sync service”问题的解决

本人不止一次在使用EndNote软件时遇到过“EndNote could not connect to the online sync service”这个问题。 过去遇到这个问题都是用这个方法来解决: 这个方法虽然能解决,但工程量太大,每次做完得歇半天身体才能缓过来。 后来再遇到该问…

私有化部署视频平台EasyCVR宇视设备视频平台如何构建视频联网平台及升级视频转码业务?

在当今数字化、网络化的时代背景下,视频监控技术已广泛应用于各行各业,成为保障安全、提升效率的重要工具。然而,面对复杂多变的监控需求和跨区域、网络化的管理挑战,传统的视频监控解决方案往往显得力不从心。 EasyCVR视频融合云…

Ubuntu从入门到精通(二)远程和镜像源配置齐全

Ubuntu从入门到精通(二) 1 常见操作配置 1.1 英文语言配置 1.1.1 打开设置 1.1.2 设置语言为英文 1.1.3 重启生效 1.1.4 再次进入,选择更新名字 1.1.5 再次进入,发现已经变成了英文 1.2 输入法配置 1.3 rustdesk安装 1.3.1 Windows系统配置 登陆:https://github.com…

【Node.js】全面解析 Node.js 安全最佳实践:保护您的应用

Node.js 是一种强大的 JavaScript 运行时,广泛用于构建现代 Web 应用和 API。然而,由于其开放性和异步特性,Node.js 应用容易受到多种安全威胁的攻击,比如 SQL 注入、跨站脚本 (XSS) 和拒绝服务攻击 (DoS)。在本文中,我…

Spring Cloud Alibaba、Spring Cloud 与 Spring Boot各版本的对应关系

参考spring-cloud-alibaba github wiki说明:版本说明 下面截取说明: 2022.x 分支 2021.x 分支 2.2.x 分支 组件版本关系

ChatGPT Search VS Kimi探索版:AI搜索哪家强?!

大家好,我是木易,一个持续关注AI领域的互联网技术产品经理,国内Top2本科,美国Top10 CS研究生,MBA。我坚信AI是普通人变强的“外挂”,专注于分享AI全维度知识,包括但不限于AI科普,AI工…

Linux常用命令,持续更新钟

在Linux系统中,你可以使用多种命令来拷贝和移动文件及目录。以下是常用的几个命令及其用法: 一、拷贝文件或目录 cp 命令 cp 命令用于拷贝文件或目录。 拷贝文件: cp source_file destination_file 例如: cp file1.txt /hom…

基于SpringBoot的校园二手商品在线交易系统+含项目运行说明文档

一、项目技术栈 二、项目功能概述 管理员可以完成的功能包括管理员登录、管理员首页展示、系统设置、物品管理、学生管理、评论管理、举报管理、新闻公告、网站设置等,前台的客户可以进行查看所有商品分类、搜索商品、登录或注册、发布商品、求购商品等。 三、部分…

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk)

MATLAB实现GARCH(广义自回归条件异方差)模型计算VaR(Value at Risk) 1.计算模型介绍 使用GARCH(广义自回归条件异方差)模型计算VaR(风险价值)时,方差法是一个常用的方法。GARCH模型能够捕捉到金融时间序列数据中的波…

动态规划 —— 子数组系列-乘积为正数的最长子数组长度

江河入海,知识涌动,这是我参与江海计划的第4篇。 1. 乘积为正数的最长子数组长度 题目链接: 1567. 乘积为正数的最长子数组长度 - 力扣(LeetCode)https://leetcode.cn/problems/maximum-length-of-subarray-with-posit…

C语言-详细讲解-洛谷P1420 最长连号

1.题目要求 2.题目分析 考虑到说明里的数据规模&#xff0c;我们可以用动态内存分配来创建合适大小的数组&#xff0c;避免栈溢出问题&#xff0c;通过循环遍历&#xff0c;最终找到最长连号。 3.代码实现 #include <stdio.h> #include <stdlib.h>int main() {…

Python Matplotlib 数据可视化全面解析:选择它的七大理由与入门简介

Python Matplotlib数据可视化全面解析&#xff1a;选择它的七大理由与入门简介 本文介绍了Matplotlib这一强大而灵活的数据可视化工具&#xff0c;涵盖其基本概念、独特优势以及为何在众多Python绘图库中脱颖而出。Matplotlib具有广泛的社区支持、高度自定义能力、多样的绘图类…

《基于 PySpark 的电影推荐系统分析及问题解决》

以下是一篇关于上述代码的博客文章&#xff1a; 基于PySpark的电影推荐系统实现与分析 在当今数字化时代&#xff0c;个性化推荐系统在各个领域中都发挥着至关重要的作用&#xff0c;尤其是在娱乐行业&#xff0c;如电影推荐。本文将详细介绍如何使用PySpark构建一个简单的电…

ant-design-vue中table组件多列排序

antD中table组件多列排序 使用前注意实现效果图实现的功能点及相关代码1. 默认按某几个字段排序2. 点击排序按钮可同时对多个字段进行排序3. 点击重置按钮可恢复默认排序状态。 功能实现完整的关键代码 使用前注意 先要确认你使用的antD版本是否支持多列排序&#xff0c;我这里…

【华为】配置VXLAN构建虚拟网络实现相同网段互通(静态方式)

微思网络 厦门微思网络 组网需求 企业已经建成比较成熟的园区网络&#xff0c;但是没有专用的数据中心网络&#xff0c;所有的服务器分布在不同的部门&#xff0c;并且不具备集中放置的条件。现在用户希望在已有园区网络上构建一个虚拟网络&#xff0c;需求如下&#xff1a; 将…

神经网络问题之:梯度不稳定

梯度不稳定是深度学习中&#xff0c;特别是在训练深度神经网络时常见的一个问题&#xff0c;其本质涉及多个方面。 一、根本原因 梯度不稳定问题的根本原因在于深度神经网络的结构和训练过程中的一些固有特性。随着网络层数的增加&#xff0c;梯度在反向传播过程中会逐层累积变…

AI工具百宝箱|任意选择与Chatgpt、gemini、Claude等主流模型聊天的Anychat,等你来体验!

文章推荐 AI工具百宝箱&#xff5c;使用Deep Live Cam&#xff0c;上传一张照片就可以实现实时视频换脸...简直太逆天&#xff01; Anychat 这是一款可以与任何模型聊天 &#xff08;chatgpt、gemini、perplexity、claude、metal llama、grok 等&#xff09;的应用。 在页面…

云原生之k8s服务管理

文章目录 服务管理Service服务原理ClusterIP服务 对外发布应用服务类型NodePort服务Ingress安装配置Ingress规则 Dashboard概述 认证和授权ServiceAccount用户概述创建ServiceAccount 权限管理角色与授权 服务管理 Service 服务原理 容器化带来的问题 自动调度&#xff1a;…