(六) Redis缓存读写策略

news2024/11/16 1:19:22

一 引言

缓存的引入后极大的提高了服务器的访问速率,但是当持久化数据发生变化时,如何更新缓存成为了研发中不可规避的问题,不同的方案决定缓存的最终的一致性,本文就redis的缓存读写策略,以及其他的缓存读写策略做简要概述

二 Cache Aside Pattern(旁路缓存模式)

Cache Aside Pattern是一种比较常用的缓存模式,适合读比较多的场景

Cache Aside Pattern 中服务端需要同时维系db和cache,并且是以db 的结果为准。

2.1 读写策略

在这里插入图片描述
写策略

  • 新更新db
  • 然后直接删除cache

读策略

  • 从cache中读取数据,读取到数据就直接返回
  • cache中读不到的话,就从db中读取数据返回
  • 再把读取到是数据放到cache中

2.2 缓存更新顺序

2.2.1 先更新缓存,在更新DB

假设「请求 A 」和「请求 B 」两个请求,同时更新「同一条」数据,则可能出现这样的顺序
A 请求先将缓存的数据更新为 1,然后在更新数据库前,B 请求来了, 将缓存的数据更新为 2,紧接着把数据库更新为 2,然后 A 请求将数据库的数据更新为 1, 出现了缓存和数据库中的数据不一致的现象

在这里插入图片描述

2.2.2 先更新DB,在更新缓存

请求 A 」和「请求 B 」两个请求,同时更新「同一条」数据,则可能出现这样的顺序:
A 请求先将数据库的数据更新为 1,然后在更新缓存前,请求 B 将数据库的数据更新为 2,紧接着也把缓存更新为 2,然后 A 请求更新缓存为 1。此时,数据库中的数据是 2,而缓存中的数据却是 1, 出现了缓存和数据库中的数据不一致的现象
在这里插入图片描述

2.2.3 先删除缓存,再更新数据库

假设某个用户的年龄是 20,请求 A 要更新用户年龄为 21,所以它会删除缓存中的内容。这时,另一个请求 B 要读取这个用户的年龄,它查询缓存发现未命中后,会从数据库中读取到年龄为 20,并且写入到缓存中,然后请求 A 继续更改数据库,将用户的年龄更新为 21
在这里插入图片描述
最终,该用户年龄在缓存中是 20(旧值),在数据库中是 21(新值),缓存和数据库的数据不一致。
可以看到,先删除缓存,再更新数据库,在并发的时候,还是会出现缓存和数据库的数据不一致的问题

2.2.4 先更新数据库,再删除缓存

假如某个用户数据在缓存中不存在,请求 A 读取数据时从数据库中查询到年龄为 20,在未写入缓存中时另一个请求 B 更新数据。它更新数据库中的年龄为 21,并且清空缓存。这时请求 A 把从数据库中读到的年龄为 20 的数据写入到缓存中。

在这里插入图片描述
最终,该用户年龄在缓存中是 20(旧值),在数据库中是 21(新值),缓存和数据库数据不一致。

从上面的理论上分析,先更新数据库,再删除缓存也是会出现数据不一致性的问题,但是在实际中,这个问题出现的概率并不高。
因为缓存的写入通常要远远快于数据库的写入,所以在实际中很难出现请求 B 已经更新了数据库并且删除了缓存,请求 A 才更新完缓存的情况。

2.3 Cache Aside Pattern 的缺陷

缺陷 1:首次请求数据一定不在 cache 的问题

解决办法:可以将热点数据可以提前放入 cache 中。

缺陷 2:写操作比较频繁的话导致 cache 中的数据会被频繁被删除,这样会影响缓存命中率 。

解决办法:

  • 数据库和缓存数据强一致场景 :更新 db 的时候同样更新 cache,不过我们需要加一个锁/分布式锁来保证更新 cache 的时候不存在线程安全问题。
  • 可以短暂地允许数据库和缓存数据不一致的场景 :更新 db 的时候同样更新 cache,但是给缓存加一个比较短的过期时间,这样的话就可以保证即使数据不一致的话影响也比较小。

三 其他策略

3.1 Read/Write Through Pattern(读写穿透)

Read/Write Through Pattern 中服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中。cache 服务负责将此数据读取和写入 db,从而减轻了应用程序的职责。
这种缓存读写策略在开发过程中非常少见。抛去性能方面的影响,大概率是因为我们经常使用的分布式缓存 Redis 并没有提供 cache 将数据写入 db 的功能

  • 先查 cache,cache 中不存在,直接更新 db。
  • cache 中存在,则先更新 cache,然后 cache 服务自己更新 db(同步更新 cache 和 db)。

  • 从 cache 中读取数据,读取到就直接返回 。
  • 读取不到的话,先从 db 加载,写入到 cache 后返回响应。

Read-Through Pattern 实际只是在 Cache-Aside Pattern 之上进行了封装。在 Cache-Aside Pattern 下,发生读请求的时候,如果 cache 中不存在对应的数据,是由客户端自己负责把数据写入 cache,而 Read Through Pattern 则是 cache 服务自己来写入缓存的,这对客户端是透明的。和 Cache Aside Pattern 一样, Read-Through Pattern 也有首次请求数据一定不再 cache 的问题,对于热点数据可以提前放入缓存中。

3.2 Write Behind Pattern(异步缓存写入)

Write Behind Pattern 和 Read/Write Through Pattern 很相似,两者都是由 cache 服务来负责 cache 和 db 的读写
但是,两个又有很大的不同:Read/Write Through 是同步更新 cache 和 db,而 Write Behind 则是只更新缓存,不直接更新 db而是改为异步批量的方式来更新 db
很明显,这种方式对数据一致性带来了更大的挑战,比如 cache 数据可能还没异步更新 db 的话,cache 服务可能就就挂掉了
这种策略在我们平时开发过程中也非常非常少见,但是不代表它的应用场景少,比如消息队列中消息的异步写入磁盘、MySQL 的 Innodb Buffer Pool 机制都用到了这种策略。
Write Behind Pattern 下 db 的写性能非常高,非常适合一些数据经常变化又对数据一致性要求没那么高的场景,比如浏览量、点赞量。

四 总结

Redis 和 MySQL 的更新策略用的是 Cache Aside,另外两种策略主要应用在计算机系统里。

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

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

相关文章

Vue学习:键盘事件

input表单占位符-显示输入先的提示文本-placeholder属性 键盘事件keydown——按下 不需要松手 keyup&#xff1a;按下松手 根据按键编码进行判断 --输出event上有一个属性-keyCode -按键编码--回车13 <!-- 准备容器 --><div idroot> <input type"text&quo…

Docker安装和使用

一&#xff1a;docker安装 链接: https://pan.baidu.com/s/1A1g7rSOMoV4__Me_zJoB3Q?pwd6bqi 提取码: 6bqi 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 --来自百度网盘超级会员v4的分享。 二&#xff1a;docker使用 1.docker和虚拟机的区别&#xff1a; …

Word文档如何设置成不可编辑的模式?

把Word文档设置成“不可编辑模式”&#xff0c;也就是“限制编辑”&#xff0c;可以防止意外更改文档内容&#xff1b;对于只想给他人读阅&#xff0c;禁止复制和更改的情况&#xff0c;也能起到一定的保护作用。 Word文档里自带设置限制保护的选项&#xff0c;在菜单中选择【…

【Uni-App】uniapp使用uview实现弹出键盘输入密码/验证码功能

目录&#xff08;一&#xff09;效果图&#xff08;二&#xff09;使用组件说明keyboard属性&#xff1a;keyboard事件&#xff1a;&#xff08;五&#xff09;js代码实现&#xff08;一&#xff09;效果图 &#xff08;二&#xff09;使用组件说明 组件使用的是uview组件&…

MATLB|多微电网及分布式能源交易

目录 一、概述 二、数学模型 三、结果可视化 四、Matlab代码实现 一、概述 在人类、工业和电动汽车的能源需求的推动下&#xff0c;全球能源需求预计将在未来几年稳步增长&#xff1b;更准确地说&#xff0c;预计到 2030 年增长将达到 40%。这种需求是由人类日益依赖能源的…

Linux配置网络,增添网络会话,Wget下载,yum仓库配置

配置网络 从RHEL7开始引入了一种新的“一致网络设备命名”的方式为网络接口命名&#xff0c;该方式可以根据固件、设备 拓扑、设备类型和位置信息分配固定的名字。网络接口的名称的前两个字符为网络类型符号。如: en——表示以太网(Ethernet)、wl表示无线局域网(wlan)、ww表示无…

[附源码]Python计算机毕业设计SSM基于的高校在线办公系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

【玩转ChatGPT |OpenAI超级对话模型】手把手带你玩转ChatGPT

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;喜欢编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;hmmwx53 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc…

【深度学习】PyTorch深度学习实践 - Lecture_10_Basic_CNN

文章目录一、CNN基础流程图二、CNN的两个阶段三、卷积的基本知识3.1 单信道的卷积3.2 三信道的卷积3.3 N信道卷积3.4 输入N信道-输出M信道卷积3.5 卷积层的常见参数3.5.1 Padding3.5.2 Stride3.5.3 下采样&#xff08;MaxPooling&#xff09;四、实现一个简单的CNN4.1 网络结构…

【案例教程】气象数值预报WRF-DA资料同化系统理论、运行与变分、混合同化新方法技术

【视频教程】WRF DA资料同化系统理论、运行与与变分、混合同化新方法技术应用https://mp.weixin.qq.com/s?__bizMzAxNzcxMzc5MQ&mid2247518760&idx1&snddbc45296acc595402434b88bc179a27&chksm9be39538ac941c2eabab2492e997827d0e1269de3b229fadee72f1223bbcd…

机器学习实战教程(三):决策树实战篇

一、前言 上篇文章机器学习实战教程&#xff08;二&#xff09;&#xff1a;决策树基础篇之让我们从相亲说起机器学习实战教程&#xff08;二&#xff09;&#xff1a;决策树基础篇_M_Q_T的博客-CSDN博客机器学习实战教程&#xff08;二&#xff09;&#xff1a;决策树基础篇之…

web前端期末大作业 html+css+javascript汽车销售网站 学生网页设计实例 企业网站制作

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

JQuery高级(回调函数 clearInterval 插件)

回调函数&#xff1a; 定义&#xff1a;回调函数被认为是一种高级函数&#xff0c;一种被作为参数传递给另一个函数的高级函数。回调函数的本质是一种模式(一种解决常见问题的模式)&#xff0c;因此回调函数也被称为回调模式。 简而言之&#xff1a;一个函数在另一个函数中…

Vue3+Vite项目按需自动导入配置及常见问题修复

文章目录一、Vue API自动导入1.1 配置unplugin-auto-import1.2 可能遇到ts,eslint不识别而导入报错的问题1.3 配置src/component目录下的组件自动引入二、按需引入UI组件库&#xff08;antd,element-plus&#xff09;2.1、按需引入element-plus2.2 ant-design-vue 按需引入2.3 …

Qt多线程调用gdal库接口

作者:朱金灿 来源:clever101的专栏 为什么大多数人学不会人工智能编程?>>> 效果图和程序说明 效果图如下: 这个程序是Qt的GUI程序,用于给指定的图像文件创建金字塔。 为什么要使用多线程 使用多线程的好处主要有两点: 1.多线程在很多时候显得更人性化些。比…

计算机研究生就业方向之去大厂做售前

我一直跟学生们说你考计算机的研究生之前一定要想好你想干什么&#xff0c;如果你只是转码&#xff0c;那么你不一定要考研&#xff0c;至少以下几个职位研究生是没有啥优势的&#xff1a; 1&#xff0c;软件测试工程师&#xff08;培训一下就行&#xff09; 2&#xff0c;前…

【Docker】如何用Docker安装Tomcat

专栏精选文章 《Docker是什么&#xff1f;Docker从介绍到Linux安装图文详细教程》《30条Docker常用命令图文举例总结》《Docker如何构建自己的镜像&#xff1f;从镜像构建到推送远程镜像仓库图文教程》《Docker多个容器和宿主机之间如何进行数据同步和数据共享&#xff1f;容器…

关于linux下的xinetd服务

我们在网络通信时候用到socket套接字&#xff0c;有的时候我们更希望Linux能使用http协议等于前端有一定的交互&#xff0c;那么xinetd服务无疑是Linux下一种很好的方法。 什么是xinetd呢&#xff1f;xinetd是新一代的网络守护进程服务程序&#xff0c;又叫超级Internet服务器,…

[附源码]Python计算机毕业设计SSM基于的婚恋系统(程序+LW)

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

ERStudio操作指南

ERStudio操作指南一、创建逻辑模型二、生成SQL脚本本文使用的ER/Studio版本&#xff1a;ER/Studio Version 8.0.2 一、创建逻辑模型 1、打开ER/Studio后&#xff0c;选择&#xff1a;File>New&#xff0c;打开如下界面&#xff0c;选择Draw a new data model。 如上图&am…