Redis如何保证数据一致性?

news/2024/5/20 12:19:19

Redis如何保证数据一致性?

Redis通常作为持久层数据库(例如MySQL)的缓存层,如果缓存或者数据库数据发生改变,如何保证双方的数据是一致的?

在这里插入图片描述

这其实是要分情况讨论滴,对数据一致性不同的要求有不同的解决方案,主要分为一致性要求高的(最终一致性、绝对一致性),一致性要求低的

数据一致性要求高

Cache Aside Pattern旁路缓存策略

双写一致性:当修改了数据库的数据也同时更新缓存的数据,缓存和数据库的数据保持一致

  1. 当数据提交更新时,先删除缓存,再更新数据库
  2. 当数据提高更新时,先更新数据库,再删除缓存

但是这两种方案都存在脏数据的风险

先删除缓存,再更新数据库,假如在线程1更新数据库的期间,有其他的线程访问数据,那么所有的线程都会去访问到数据库,并且拿到的是旧数据,放入到缓存中

在这里插入图片描述

先更新数据库,再删除缓存,假如在线程1查询数据库的期间,其他线程对数据库进行了修改,并且删除了缓存,在线程1查询完数据过后将旧的数据写入到了缓存中

在这里插入图片描述

总而言之,无论先删除缓存还是先更新数据库都会存在数据不一致的问题,但是先更新数据库再删除缓存产生数据不一致的概率比较低,因为写入缓存的速度一般是远远快于更新数据库的操作,并且如果数据库更新失败,先删缓存,缓存不会回滚,而后删缓存,数据库更新失败,缓存不会被删除

延迟双删

延迟双删,在写库完成后,删除缓存,写库的线程睡眠一段时间再次删除缓存

在这里插入图片描述

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

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

如何避免删除缓存失败的情况?

MQ方案

在这里插入图片描述

可以使用一个MQ队列接受删除失败的key,使用一个消费者监听MQ队列,一旦有删除Redis失败的消息,就去进行删除重试

监听binlog日志

在这里插入图片描述

阿里巴巴有一个专门的中间件,负责监听binlog日志,一旦binlog发生了变动,cannel就会通知cannel的客户端,cannel客户端负责进行缓存的删除操作(同时支持重试)

总结:这两种方案核心就是将删除缓存的操作异步化了,并且支持重试

难道没有保证数据绝对一致性的方案吗?读写锁

读写锁(数据绝对一致性)

读写锁:给读操作加读锁,给写操作加写锁,读锁允许其他线程进行读操作但是不能进行写操作写锁不允许其他线程进行读、写操作

例如下面这个栗子

当线程对数据进行读操作,其他所有对数据进行写操作的线程都将被阻塞,但是可以进行读操作

在这里插入图片描述

当线程对数据进行写操作时,其他所有对数据进行读写操作的线程都将被阻塞

在这里插入图片描述

优点:读写锁保证了数据库与缓存之间的数据强一致性

缺点:加上读写锁之后,访问数据的速度将变得缓慢,有点违背了加缓存的初衷,所以,但你的数据是写多于读的,不建议放入缓存中

数据一致性要求低

系统对于数据的实时一致性要求没那么高,例如视频播放量、点赞数、社交媒体动态

怎么解决?

  1. 异步更新策略:使用MQ作为消息中间件,更新缓存后,通知缓存删除
  2. 缓存失效策略:设置合适的缓存失效时间,让缓存在一定时间内保持一致性,在超时后从数据库获取新数据即可

总结

对于数据一致性高的场景,旁路缓存中先更新数据库再删缓存已经能保证绝大情况下的数据一致性,如果要求再高点可以考虑上延迟双删,同时加中间件避免缓存删除失败。不推荐上读写锁,因为缓存本身就是为了提高性能的,读写锁对性能的影响较大。


http://www.mrgr.cn/p/05417113

相关文章

C++ 数组元素操作

数组元素的移除核心思路:创建一个新的内存空间存储移除后的数组,再将原数组delete释放,再将指针指向新数组。cout << "----------------------------- 数组元素的移除 -------------------------" << endl; //cout << deleteArrByIndex(0, arr1…

如何优化工服识别算法的漏报与误报问题

背景 在一些行业&#xff0c;例如工厂、建筑工地、医院等&#xff0c;员工通常需要穿着特定的工服&#xff0c;工服有助于识别员工、保护员工免受潜在危险以及维护生产环境的清洁度。因此&#xff0c;开发工服识别算法并运用在未穿工服检测系统具有重要的实际意义。 尽管工服…

基于改进Bert模型的夸夸聊天机器人(1)数据预处理篇

目录项目概述数据预处理数据爬取数据清洗构建敏感词字典树去除不相关问题和回答去除敏感词去除HTML标签去除标点符号去除emoji去除夸夸词过滤长度,转换格式 项目概述 该项目构建一个基于UniLM的生成式夸夸bot UniLM 是在微软研究院在BERT的基础上,最新产出的预训练语言模型,被称…

网络工程师必备:静态路由实验指南

大家好&#xff0c;这里是G-LAB IT实验室。今天带大家学习一下华为静态路由实验配置 01、实验拓扑 02、实验需求 1.R1环回口11,1,1.1模拟PC1 2.R2建立2个环回口模拟Server server-1: 22,1,1.1 server-2: 44.1.1.1 3.要求使用静态路由实现全网互通 PC1去往server-1从R3走…

当字符遇上 scanf() 要当心

当字符遇上 scanf() 要当心 看一下程序char ch1,ch2;printf("请输入ch1,ch2的值:");scanf("%c %c",&ch1,&ch2);printf("ch1 = %c, ch2 = %c\n",ch1,ch2);printf("请再次输入ch1的值:");scanf("%c",&ch1);printf…

结构分析的有限元法及matlab实现(徐荣桥)|【PDF教材+配套案例Matlab源码】

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《有限元编程从入门到精通》本专栏旨在提供 1.以案例的形式讲解各类有限元问题的程序实现&#xff0c;并提供所有案例完整源码&#xff1b;2.单元…

必读干货!国内验证签发的SSL证书六大优势

JoySSL官网 注册码230918 国内验证签发的SSL证书&#xff0c;作为网络安全基础设施的重要组成部分&#xff0c;对于维护互联网数据安全、保障用户隐私、提升网站信誉度具有不可小觑的作用。特别是在当前数字化转型加速、数据合规要求日益严格的背景下&#xff0c;选择国内验证签…

瞬回丝滑!30秒解决win11文件管理器卡顿问题!

命令文本:reg add "HKCU\Software\Classes\CLSID\{d93ed569-3b3e-4bff-8355-3c44f6a52bb5}\InprocServer32" /f /ve 如需取消输入这个命令 reg delete "HKCU\Software\Classes\CLSID\{d93ed569-3b3e-4bff-8355-3c44f6a52bb5}" /f

k8s资源编排-yml介绍

yaml文件: 叫做“资源清单文件”,通过kubecl命令直接使用yaml文件就可以实现对大量的资源对象进行编排部署了。2.Yaml的组成部分 yaml由2个部分组成: 2.1 控制器定义 2.2 被控制对象 yaml文件自己写比较繁琐,还好有自动生成yml格式文件的方式: 1.使用kubectl create命令生…

算法day02

1、202. 快乐数 如上题所述&#xff1a; 在该题意规则下&#xff0c;所有的数字变化会有两种情况&#xff0c;其一最后是有的会变化成恒为1的数&#xff1b;其二是有的数会变化会呈现成有规律的环&#xff0c;分别如下图所示&#xff1a; 可以近似的理解为图一就是一个环&#…

Stable Diffusion WebUI 页面设置: 显示 VAE CLIP

目标效果:步骤:到设置Settings页面 -- 搜索 Quicksettings 在列表框中输入 sd_vae 和 CLIP_stop_at_last_layers最后 Apply settings 并 Reload UI完成================# 水平有限 欢迎指正 #=================

【SpringBoot整合系列】SpringBoot整合Thymeleaf

目录 背景Thymeleaf简介Thymeleaf的特征模板引擎是什么 代码示例1.引入依赖2.修改配置文件&#xff0c;添加Thymeleaf的配置信息3.编写HTML模板文件4.编写控制器&#xff0c;返回ModelAndView&#xff0c;进行视图渲染 Thymeleaf语法1.常用标签/属性1.1 th:action1.2 th:method…

Qt常用基础控件总结

一、按钮部件 按钮部件共同特性 Qt 用于描述按钮部件的类、继承关系、各按钮的名称和样式,如下图: 助记符:使用字符"&“可在为按钮指定文本标签时设置快捷键,在&之后的字符将作为快捷键。比如 “A&BC” 则 Alt+B 将成为该按钮的快捷键,使用”&&qu…

React文本溢出组件封装以及高亮提示

React文本溢出组件封装以及高亮提示Abbr 组件:使用场景:当我们需要设置支持最大行数时进行省略展示 当我们需要设置支持设置超过多少字符进行省略展示 当我们需要设置支持关键字高亮展示(有点问题,当关键字被裁剪成...之后,就无法高亮) 当我们需要支持忽略大小写高亮 当我…

边缘智能网关P1600,智慧林业的得力助手

随着科技的不断发展&#xff0c;人工智能、物联网、大数据等先进技术在林业领域的应用日益广泛&#xff0c;为林业管理带来了革命性的变革。智慧林业的核心目标是实现林业资源的数字化、网络化和智能化&#xff0c;从而提高林业管理的效率和水平。边缘智能网关P1600作为一种新型…

AlmaLinux 9.4 正式版发布 - RHEL 二进制兼容免费发行版

AlmaLinux 9.4 正式版发布 - RHEL 二进制兼容免费发行版AlmaLinux 9.4 正式版发布 - RHEL 二进制兼容免费发行版 由社区提供的免费 Linux 操作系统,RHEL 二进制兼容发行版 请访问原文链接:AlmaLinux 9.4 正式版发布 - RHEL 二进制兼容免费发行版,查看最新版。原创作品,转载…

cc6链:绕过cc1的jdk限制

这里回到LazyMap,LazyMap的get方法可以触发后续的rce为什么cc1有jdk版本限制 JDK中的AnnotationInvocationHandler的readObject更新了,所以cc1用不了 但是前面的部分还是存在的,只要我们找到一个新的入口就还是能执行命令 这里回到LazyMap,LazyMap的get方法可以触发后续的r…

第二届数信杯南区wp-easyJava

第二届数信杯南区easyJavawriteup easyJava 用Eclipse Memory Analyzer进行分析,利用OQL查找字符串这里要写正则表达式:我写了\\u.*意思是找unicode字符串,因为这里的中文都做了unicode编码搜索到这么一个字符串列表,转码——红色框框里的是还原后的内容。如下: 想跟你说一…