Redis高级系列-缓存双写一致性

Redis高级系列-缓存双写一致性

文章目录

  • Redis高级系列-缓存双写一致性
    • 1. 什么叫做缓存双写一致性?
    • 2. 缓存双写一致性有那些解决方案?
      • 2.1 Cache Aside Pattern(旁路缓存模式)
        • 延迟双删
        • 重试删除
        • binlog订阅异步删除
      • 2.2 Read Through/Write Through(读写穿透)
        • 使用场景
      • 2.3 Write Behind(后写或异步写)
        • 使用场景
    • 3. 总结

1. 什么叫做缓存双写一致性?

Redis缓存双写一致性是指在更新数据库数据后,同时更新缓存数据以保持数据一致性的策略,总的来说,就是写入redis写入数据库的数据要保持一致

2. 缓存双写一致性有那些解决方案?

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

旁路缓存模式,字面意思理解:缓存是旁路,缓存相对与应用程序和数据库是旁路,应用程序可以直接绕过缓存访问数据库

在Cache Aside模式中,应用程序首先从缓存中读取数据,如果缓存中不存在,则从数据库中读取数据,并将数据写入缓存中。在更新数据时,应用程序首先更新数据库中的数据,然后删除缓存中的数据。当下一次请求到来时,应用程序会从数据库中读取最新的数据,并将其写入缓存中

那为什么要先更新数据库在删除缓存了?我们再看看几种更新策略

策略是否是多线程场景现象
先删除缓存再更新数据库删除缓存成功但数据库更新失败应用程序从数据库中读到旧值
缓存删除成功但数据库再更新中…有并发读请求并发读请求从数据库读到旧值,并回写到redis,导致后续都从redis读取到旧值
先更新数据库再删除缓存数据库更新成功,但缓存删除失败应用程序从redis读取到旧值
数据库更新成功,但缓存再删除中…有并发读请求并发读请求读取到旧值
先更新缓存再更新数据库更新缓存成功但更新数据库失败缓存和数据库数据不一致(不推荐,一般数据库作为兜底方案)
更新缓存成功但数据库再更新中缓存和数据库数据不一致(不推荐,一般数据库作为兜底方案)
先更新数据库再更新缓存更新数据库成功但缓存更新失败应用程序读取到旧值
更新数据库成功但缓存再更新中…有并发读请求并发读请求读取到旧值
延迟双删

经过我们对Cache Aside Pattern四种方案的八种场景进行仔细分析,我们大体上确定了先更数据库再删缓存的方案。但是这种方案也并不完美,假设我们更新数据库成功了,删除缓存失败了,那么同样会出现一致性问题。为了解决这种场景下的一致性问题,我们进一步引入了延迟双删方案来解决。

  • 为什么要做两次缓存删除呢?

从上图“延迟双删”中我们可以很清晰地看到,数据库的更新是在首次的缓存删除成功后进行的,这样就有效避地免了“先更数据库再删缓存”方案中可能出现的数据库更新成功缓存删除失败导致的一致性问题。第二次的缓存删除是为了避免在执行更新数据库操作完成之前其它线程读取数据库并更新缓存而导致的一致性问题。

  • 为什么第二次缓存删除又要延迟执行呢?

试想,如果我们不做第二次的延迟删除,而是更新数据库后立即删除会出什么问题?有没有可能其它读请求线程在更新数据库之前读取了数据,并在第二次立即删除缓存之后更新了缓存。很明显,延迟删除就是为了让可能存在的其它读请求线程尽可能地在更新完缓存后再执行缓存删除操作。这样一通操作后,数据库是最新的数据了,缓存里没有数据,后面的读请求线程又可以拿到数据库的最新数据写入缓存了。

  • 延迟删除具体需要延迟多长时间?

对于这个具体需要延迟多长时间,其实没有绝对的标准,唯一的标准就是根据读请求的耗时来确定,读请求越耗时,延迟时间越长。一般情况下我们设置的延迟时间为1秒。

重试删除

在上面的延迟双删方案中,如果我们思考,其实还是有诸多问题的。比如:在延迟双删的读写场景中,如果第二次缓存删除失败了,同样会出现一致性问题。那么删除失败了,重试几次不就好了吗?基于这个思想我们进一步引入了重试删除方案来解决

重试删除确实很大程度上解决了一致性问题,并且逻辑非常简单。唯一的不足可能就是需要引入消息队列,并且业务代码也会有一定的侵入。那么有没有既能够保证最终一致性,又能够解耦的方案呢?我们继续往下面看

binlog订阅异步删除

binlog订阅异步删除确实也能解决一致性问题,对代码也无任何侵入,但是整个架构复杂,中小项目一般都用不上。

2.2 Read Through/Write Through(读写穿透)

该策略又被称为读穿/写穿策略,和CacheAside策略的缓存数据与数据库数据为准不同,该策略的核心是用户只与缓存层交互(应用程序只与缓存或者中间层、缓存抽象层交互),由缓存层与数据库通信,写入或读取数据。

在读取数据时,通过缓存层进行读取,若缓存存在则直接返回,若不存在则由缓存层拉取数据库数据到缓存中并返回。
在写数据时,通过缓存层进行写入,若缓存存在则直接写入缓存中并同步到数据库,若不存在则写入数据库中。

使用场景

适用于读多写多的场景,数据一致性要求较高的场景。

2.3 Write Behind(后写或异步写)

Write Behind Caching是一种将缓存和数据库异步写入的缓存模式。在Write Behind Caching模式中,应用程序首先将更新操作写入缓存中,然后异步地将更新操作写入数据库中。当下一次请求到来时,应用程序会从缓存中读取数据,并将其写入数据库中。

使用场景

适用于写多读少的场景,数据一致性要求不高的场景

3. 总结

在使用Redis缓存时,应根据具体的业务场景和需求选择合适的缓存模式。Cache Aside模式简单易用,适用于读多写少的场景;Read/Write Through模式完全解耦缓存和数据库,适用于读多写多的场景;Write Behind Caching模式可以提高写入性能,适用于写多读少的场景。在实际应用中,可以根据具体的业务需求和性能要求,选择合适的缓存模式,以提高系统的性能和稳定性。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LightGlue: Local Feature Matching at Light Speed

一、论文概述 发表于: 2023 ICCV 作者信息:Philipp Lindenberger Paul-Edouard Sarlin Marc Pollefeys 对比算法:SuperGlue 代码:github.com/cvg/LightGlue 效果: 现有问题: 1) SuperGlue 与其他基于 …

“尔滨”宠粉再升级!百亿像素VR冰雪盛宴

1月10日,由哈尔滨市委网信办、哈尔滨日报社主办,冰城客户端、哈尔滨新闻网承办的“激情迎亚冬,冰雪暖世界——2024年哈尔滨冰雪乐园”VR沉浸式体验产品正式上线。 如果你还没去过最近爆火出圈的“尔滨” ❄️这份哈尔滨冰雪景点VR❄️ 为你…

初识 Elasticsearch 应用知识,一文读懂 Elasticsearch 知识文集(4)

🏆作者简介,普修罗双战士,一直追求不断学习和成长,在技术的道路上持续探索和实践。 🏆多年互联网行业从业经验,历任核心研发工程师,项目技术负责人。 🎉欢迎 👍点赞✍评论…

HDClone X.5 新版功能亮点

在 HDClone X.4 版本的基础上,HDClone X.5 新版本推出了对网盘、映射磁盘等的镜像功能,让磁盘镜像更加如虎添翼。 创建卷的镜像:可将非物理介质作为卷,对其制作镜像,从而保护其中数据。挂载这些镜像后,即可直接访问其中的文件,设置的保护层可以确保文件不被更改。 用于存…

小程序系列--8.页面事件

一、下拉刷新事件 1. 什么是下拉刷新? 下拉刷新是移动端的专有名词,指的是通过手指在屏幕上的下拉滑动操作,从而重新加载页面数据的行为。 2. 启用下拉刷新 3. 配置下拉刷新窗口的样式 4. 监听页面的下拉刷新事件 在页面的 .js 文件中&am…

FastAPI 并发请求详解:提升性能的关键特性

在当今的数字化世界中,网络用户对于高速响应和持续连接的诉求日益显著。这促使了基于 Python 构建的 FastAPI 框架受到广泛关注,它不仅现代化且效率极高,而且简化了并行请求的处理。本篇文章旨在探讨 FastAPI 如何处理这类请求,并…

【遥感专题系列】影像信息提取之——面向对象的影像分类技术

“同物异谱,同谱异物”会对影像分类产生的影响,加上高分辨率影像的光谱信息不是很丰富,还有经常伴有光谱相互影响的现象,这对基于像素的分类方法提出了一种挑战,面向对象的影像分类技术可以一定程度减少上述影响。 本…

【AI接口】语音版、文心一言大模型和AI绘图、图片检测API

文章目录 一、语音版大模型AI1、接口2、请求参数3、请求参数示例4、接口返回示例 二、AI图片鉴黄合规检测API1、接口2、请求参数3、请求参数示例4、接口返回示例5、报错说明6、代码开源 三、人工智能AI绘画API1、接口2、请求参数3、请求参数示例4、接口返回示例5、AI绘画成果展…

Redis(四)

1、Redis的单/多线程 1.1、单线程 其实直接说Redis什么单线程或者是多线程,不太准确,在redis的4.0版主之前是单线程,然后在之后的版本中redis的渐渐改为多线程。 Redis是单线程主要是指Redis的网络IO和键值对读写是由一个线程来完成的&#…

安全高效、成本低廉:云桥通SD-WAN企业组网解决企业全球网络挑战

安全高效、成本低廉:云桥通SD-WAN企业组网解决企业全球网络挑战 随着企业规模的扩张和数字化转型的加速,面对分布全球的总部、分支机构、门店、数据中心和云服务之间的网络互联、数据传输和应用加速挑战,云桥通SD-WAN组网已然崭露头角。其在…

F - Digital Roots HUOJ

题目 The digital root of a positive integer is found by summing the digits of the integer. If the resulting value is a single digit then that digit is the digital root. If the resulting value contains two or more digits, those digits are summed and the pro…

SRC实战 | 任意密码重置绕过

本文由掌控安全学院 - 叴龙 投稿 1.信息搜集 2.漏洞挖掘 1.信息搜集 没事干,准备找个证书站挖挖看,没想到碰到一个小通用系统。看样子还挺多功能可以测。 这里利用F12 查看前端源码js 或者css文件提取指纹,直接用hunter或者fofa搜索到同一…

WordPress设置回收站自动清理天数的插件Change Empty Trash Time

前面boke112百科跟大家分享的『WordPress回收站自动清空时间?如何关闭回收站或设置自动清理天数?』一文,就介绍了可以添加一行代码实现关闭或设置回收站自动清理时间,也可以通过安装Change Empty Trash Time插件来实现。 今天bok…

Vue基础入门 - Vue的快速创建、Vue的开发者工具安装及Vue的常用指令(v-model,v-bind,computed计算属性,watch侦听器)

Vue 文章目录 Vue1 什么是Vue2 创建Vue实例2.1 快速创建2.2 插值表达式 {{}}2.3 响应式特性2.3.1 访问与修改 3 Vue开发者工具安装4 Vue中的常用指令4.1 内容渲染指令4.2 条件渲染指令4.3 事件绑定指令4.4 属性绑定指令4.5 案例-上下页图片翻页4.6 列表渲染指令4.7 案例-能删除…

《SPSS统计学基础与实证研究应用精解》视频讲解:参数估计

《SPSS统计学基础与实证研究应用精解》2.5 视频讲解 视频为《SPSS统计学基础与实证研究应用精解》张甜 杨维忠著 清华大学出版社 一书的随书赠送视频讲解2.5节内容。本书已正式出版上市,当当、京东、淘宝等平台热销中,搜索书名即可。本书旨在手把手教会使…

【数字人】10、HyperLips | 使用 audio 实现高保真高清晰的唇部驱动

文章目录 一、背景二、相关工作2.1 Audio-Driven Talking Face Generation2.2 HyperNetwork2.3 Prior Based Face Restoration 三、方法3.1 Base Face Generation3.2 High-Fidelity Rendering 四、效果 论文:HyperLips: Hyper Control Lips with High Resolution De…

[Android] Android架构体系(2)

文章目录 Bionic精简对系统调用的支持:不支持 System V IPC:有限的 Pthread 功能:有限支持C:不再支持本地化和/或宽字符:Bionic新增的特性系统属性硬编码写死的UID/GID内置了DNS解析硬编码写死的服务和协议 硬件抽象层Linux内核匿名共享内存(ASHMem)BinderLoggerION 内存管理内…

vue2嵌入高德地图选择地址后显示地址和经纬度

以高德地图为里&#xff0c;申请key&#xff0c;选择js api服务&#xff0c;获取key和密钥. vue2项目代码引入相关依赖&#xff1a; npm i amap/amap-jsapi-loader -S 封装成组件: <template><div><el-row :gutter"15" class""><…

[C++] external “C“的作用和使用场景

C++中extern "C"的作用是什么? 在 C++ 中,extern "C" 的作用是告诉编译器按照 C 语言的规范来处理函数名和变量名。这是因为 C++ 编译器会对函数名和变量名进行名称修饰(name mangling),以区分不同的函数和变量。而在 C 语言中,函数名和变量名不会被名…

【b站咸虾米】chapter4_vue组件_新课uniapp零基础入门到项目打包(微信小程序/H5/vue/安卓apk)全掌握

课程地址&#xff1a;【新课uniapp零基础入门到项目打包&#xff08;微信小程序/H5/vue/安卓apk&#xff09;全掌握】 https://www.bilibili.com/video/BV1mT411K7nW/?p12&share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 四、vue组件 uni-app官网 …
最新文章