Redis如何保证数据一致性?

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://xiahunao.cn/news/3019787.html

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

相关文章

Transformer详解:从放弃到入门(完结)

前几篇文章中,我们已经拆开并讲解了Transformer中的各个组件。现在我们尝试使用这些方法实现Transformer的编码器。   如图所示,编码器(Encoder)由N个编码器块(Encoder Block)堆叠而成,我们依次实现。 class EncoderBlock(nn.Module):def …

【求助】鸿蒙DevEco Studio 4.1 Release-模拟器启动方式错误

软件版本:DevEco Studio 4.1 Release 报错提示: 没有权限查看处理指导 Size on Disk 显示1.0MB 尝试方案(统统无效): 1、“windows虚拟机监控程序平台”、"虚拟机平台"已开启 启用CPU虚拟化 2、CPU虚…

微服务项目实战-黑马头条(十三):持续集成

文章目录 项目部署_持续集成1 今日内容介绍1.1 什么是持续集成1.2 持续集成的好处1.3 今日内容 2 软件开发模式2.1 软件开发生命周期2.2 软件开发瀑布模型2.3 软件的敏捷开发 3 Jenkins安装配置3.1 Jenkins介绍3.2 Jenkins环境搭建3.2.1 Jenkins安装配置3.2.2 Jenkins插件安装3…

pymysql用法整理--python实现mysql数据库操作

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文着重整理pymsql的常用方法 不专门讲解MySQL数据库的相关知识 常用基本语法汇总 import pymysql#连接数据库 connpymysql.connect(host127.0.0.1,port3306,userroot,password123456,charsetutf8,db"expe…

【python数据分析基础】—pandas透视表和交叉表

目录 前言一、pivot_table 透视表二、crosstab 交叉表三、实际应用 前言 透视表是excel和其他数据分析软件中一种常见的数据汇总工具。它是根据一个或多个键对数据进行聚合,并根据行和列上的分组键将数据分配到各个矩形区域中。 一、pivot_table 透视表 pivot_tabl…

git commit后发现git pull 拉取代码失败的解决方案(致命错误:需要指定如何调和偏离的分支。)

文章目录 前言一、情况复现1.以前多人开发同一分支提交代码逻辑(下拉取后提交)2.报错 二、解决方案1. 撤销最近一次提交2.提交代码3.注意点:常用的 git stash 命令: 前言 人员张三和人员李四在同一分支(dev)上开发 一、情况复现 …

大厂必备栅格系统详解与应用指南

今天,90%的媒体互动都是基于屏幕的,通过手机、平板电脑、笔记本电脑、电视和智能手表来与外界产生联系。多屏设计已成为商业设计中不可或缺的一部分,响应式设计正迅速成为常态。 作为UI设计工具,即时设计希望产品设计…

旧物回收小程序开发:打造绿色生活,共筑美好未来

随着环保意识的逐渐增强,我们越来越意识到旧物回收的重要性。为了响应这一趋势,我们精心研发了一款旧物回收小程序,旨在通过科技的力量,让每个人都能够轻松参与到旧物回收的行动中来,共同为地球环保贡献一份力量。 一…

3W 3KVDC 隔离单、双输出 DC/DC 电源模块——TPH-3W 系列

TPH-3W系列是一款3W,单、双输出隔离电源模块,特别适合板上只有一种电压而要求有正负电源的场合,工业级温度范围–40℃到105℃,在此温度范围内都可以稳定输出2W,并且效率非常高,高达86%,温升非常低&#xff…

正点原子Linux学习笔记(五)FrameBuffer 应用编程

FrameBuffer 应用编程 19.1 什么是 FrameBuffer19.2 LCD 的基础知识19.3 LCD 应用编程介绍使用 ioctl()获取屏幕参数信息使用 mmap()将显示缓冲区映射到用户空间 19.4 LCD 应用编程练习之 LCD 基本操作19.5 LCD 应用编程练习之显示 BMP 图片在 LCD 上显示 BMP 图像在开发板上测…

在 Linux 中删除文件和文件夹

目录 ⛳️推荐 前言 删除文件 🏋️练习文件删除 小心删除 删除目录 🏋️练习文件夹删除 测试你的知识 ⛳️推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到…

使用.NET8实现Web API

目录 1、环境准备1.1、从官网下载 及安装VS2022社区版1.2、下载及安装asp.net core的运行时及IIS Module 2、WebAPI工程创建2.1 创建API服务2.2 推荐的库2.2.1 数据库篇2.2.1.1、 SQLSugar2.2.1.2、 OracleAccess 2.2.2、IOC篇2.2.2.1、autofac2.2.2.2、 2.2.3、日志记录篇2.2.…

Django Admin后台管理:高效开发与实践

title: Django Admin后台管理:高效开发与实践 date: 2024/5/8 14:24:15 updated: 2024/5/8 14:24:15 categories: 后端开发 tags: DjangoAdmin模型管理用户认证数据优化自定义扩展实战案例性能安全 第1章:Django Admin基础 1.1 Django Admin简介 Dj…

【SpringBoot】使用MockMvc+Mockito进行单元测试像德芙一样纵享丝滑!

文章目录 前言:Java常见的单元测试框架一.Junit5基础二.SpringBoot项目单元测试1.添加依赖2.SpringBoot单元测试标准结构3.SpringBoot单元测试常用注解 三.单元测试中如何注入依赖对象1.真实注入(AutoWired、 Resource)2.Mock注入2.1.前言2.2…

test我说话撒机房环境

testhfsjafjdsbzvbcxn.ztesthfsjafjdsbzvbcxn.ztesthfsjafjdsbzvbcxn.ztesthfsjafjdsbzvbcxn.ztesthfsjafjdsbzvbcxn.ztesthfsjafjdsbzvbcxn.ztesthfsjafjdsbzvbcxn.ztesthfsjafjdsbzvbcxn.z

海淘美国礼品卡测评:AE/TT/香草卡与国内卡商、亚马逊测评工作室如何变现?(下)

上回分析的四种变现模式,相信大家已经了解清楚。 塔吉特礼品卡,香草礼品卡,AE礼品卡,百思买礼品卡,亚马逊礼品卡,沃尔玛礼品卡,丝芙兰礼品卡,雷蛇礼品卡,谷歌礼品卡&…

CSS定位(如果想知道CSS有关定位的知识点,那么只看这一篇就足够了!)

前言:在网页布局的时候,我们需要将想要的元素放到指定的位置上,这个时候我们就可以使用CSS中的定位操作。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨✨✨想要了解更多内容可以访问我的主页秋刀鱼不做梦-CSDN博客 先让我们看一下本篇文章的大致内容&…

在Unity中制作和使用图集

文章目录 使用Unity内置Sprite Packer使用图集NGUI图集制作(如果使用NGUI)TextMeshPro中文支持 应用案例:在Unity中创建一个使用图集的UI界面场景设定步骤概览1. 准备UI元素2. 创建Sprite Atlas3. 使用图集中的Sprite4. 调整与布局5. 动态加载…

鸿蒙内核源码分析(特殊进程篇)

三个进程 鸿蒙有三个特殊的进程,创建顺序如下: 2号进程,KProcess,为内核态根进程.启动过程中创建.0号进程,KIdle为内核态第二个进程,它是通过KProcess fork 而来的.这有点难理解.1号进程,init&#xff0c…

kubeflow简单记录

kubeflow 13.7k star 1、Training Operator 包括PytorchJob和XGboostJob,支持部署pytorch的分布式训练 2、KFServing快捷的部署推理服务 3、Jupyter Notebook 基于Web的交互式工具 4、Katib做超参数优化 5、Pipeline 基于Argo Workflow提供机器学习流程的创建、编排…