如何保证Redis缓存和数据库的一致性问题
熟练掌握Redis缓存技术?
那么请问Redis缓存中有几种读写策略,又是如何保证与数据库的一致性问题
今天来聊一聊常用的三种缓存读写策略
Cache Aside Pattern
Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景,服务端需要同时维系 db 和 cache,并且是以 db 的结果为准
那么服务端到底是先更新db还是先更新cache?
1.先更新数据库
读
- 查询缓存,缓存中查询到了直接返回
- 查询不到时查询数据库,
- 查询完数据库后将数据更新至缓存
写
- 修改数据库
- 删除缓存
那么能不能先删除缓存再更新数据库呢?
答案是 不能,这样会导致数据的不一致性
当请求A 发起写请求,此时删除缓存,同时请求B发起读请求,由于没有缓存查询数据库,随后请求A更新数据库
通常情况下,查询数据库的速度比修改数据库更快。这是因为查询操作通常只涉及对数据库中的数据进行读取和匹配,并且可以使用合适的索引来加速查询过程。相比之下,修改操作需要对数据库中的数据进行写入和更新,可能还需要触发额外的数据库约束、触发器或日志记录等操作,这些都会增加一定的开销和时间。
那么是不是先更新数据库再删除缓存是不是就没有数据不一致的情况呢?
答案是 并不是
当请求A发起读请求,恰巧此时缓存过期,需要查询数据库,此时请求B发起写请求,由于没有缓存,故不会执行删除缓存操作,请求A查询完数据库将数据写入缓存,请求B随后更新数据库
但因为要同时达成读缓存时缓存失效并且有并发写的操作,而操作缓存比操作数据库要快得多,所以概率要小很多
那么如何解决这种情况呢?
更新完数据后的时候同时更新缓存,并且我们需要加一个锁/分布式锁来保证更新 cache 的时候不存在线程安全问题,确保数据库和缓存的强一致问题
2.先更新缓存
读
- 查询缓存,缓存中查询到了直接返回
- 查询不到时查询数据库,
- 查询完数据库后将数据更新至缓存
写
- 先更新缓存
- 再更新数据库
首先如果缓存更新成功但数据库更新失败,会导致数据不一致的问题
其次当请求A发起写请求,先更新缓存,于此同时请求B发起读请求,返回数据后,数据库被更新,照成了数据不一致的情况
这种概率大吗?
大,因为redis操作比数据库操作快的多,很容易发生
redis为什么那么快?
第一,Redis 的大部分操作在内存上完成,内存操作本身就特别快;
第二,Redis追求极致,选择了很多高效的数据结构,并做了非常多的优化,比如 hash,跳表,有时候一种对象底层有几种实现以应对不同场景。
第三,Redis 采用了多路复用机制,使其在网络 IO 操作中能并发处理大量的客户端请求,IO 多路复用机制是指一个线程处理多个 IO 流,就是我们经常听到的 select/epoll 机制。简单来说,在 Redis 只运行单线程的情况下,该机制允许内核中,同时存在多个监听 Socket 和已连接 Socket。内核会一直监听这些 Socket 上的连接请求或数据请求。一旦有请求到达,就会交给 Redis 线程处理,这就实现了一个 Redis 线程处理多个 IO 流的效果。
而我们的Cache Aside Pattern采用的就是第一种情况先更新数据库,比较适合读请求比较多的场景
那么对于首次请求一定不存在cache的情况如何解决呢?
可以设置定时任务将热点数据提前放入 cache 中
Read/Write Through
原理:Read/Write Through原理是把更新数据库的操作由缓存代理,cache 服务负责将此数据读取和写入 db,从而减轻了应用程序的职责。
Read Through:如果命中缓存则直接返回数据,如果没有命中则查询数据库,随后写入到缓存中并返回
Write Through:当有数据更新的时候,如果没有命中缓存,直接更新数据库,然后返回。如果命中了缓存,则更新缓存,然后再由缓存自己更新数据库(这是一个同步操作)。
Write Behind
原理:在更新数据的时候,只更新缓存,不更新数据库,而缓存会异步地批量更新数据库。这个设计的好处就是让数据的I/O操作非常快,带来的问题是,数据不是强一致性的,而且可能会丢。
对比Read/Write Through 是同步更新 cache 和 db,而 Write Behind 则是只更新缓存,不直接更新 db,而是改为异步批量的方式来更新 db
非常适合一些数据经常变化又对数据一致性要求没那么高的场景,比如浏览量、点赞量
相关文章:
如何保证Redis缓存和数据库的一致性问题
熟练掌握Redis缓存技术? 那么请问Redis缓存中有几种读写策略,又是如何保证与数据库的一致性问题 今天来聊一聊常用的三种缓存读写策略 Cache Aside Pattern Cache Aside Pattern 是我们平时使用比较多的一个缓存读写模式,比较适合读请求比…...
【数据分析入门】人工智能、数据分析和深度学习是什么关系?如何快速入门 Python Pandas?
目录 一、前言二、数据分析和深度学习的区别三、人工智能四、深度学习五、Pandas六、Pandas数据结构6.1 Series - 序列6.2 DataFrame - 数据框 七、输入、输出7.1 读取/写入CSV7.2 读取/写入Excel7.3 读取和写入 SQL 查询及数据库表 八、调用帮助九、选择(这里可以参考上一篇文…...
JavaScript 里三个点 ... 的用法
// table表头数据let tableHeadData deepClone(data);let tableCacheData [];//表格缓存对比if (!parent && isCacheHeadData) {// 缓存数据keylet tableCacheKey ${window.location.pathname}-${$self.attr(id)}if (localStorage.getItem(tableCacheKey)) {//根据缓…...
Linux修改系统语言
sudo dpkg-reconfigure locales 按pagedown键,移动红色光标到 zh_CN.UTF-8 UTF-8,空格标记*号(没标记下一页没有这一项),回车。 下一页选择 zh_CN.UTF-8。 如果找不到 dpkg-reconfigure whereis dpkg-reconfigure …...
Spring注解开发
目录 1、简介 2、原始注解 2.1、注解种类 2.2、组件扫描 2.3、具体使用 2.3.1、xml配置 2.3.2、注解配置 3、⭐新注解 3.1、新注解种类 3.2、实践 3.3、运行结果 3.4、警告信息 1、简介 Spring框架提供了许多注解,用于在Java类中进行配置和标记…...
图像处理库(Opencv, Matplotlib, PIL)以及三者之间的转换
文章目录 1. Opencv2. Matplotlib3. PIL4. 三者的区别和相互转换5. Torchvision 中的相关转换库5.1 ToPILImage([mode])5.2 ToTensor5.3 PILToTensor 1. Opencv opencv的基本图像类型可以和numpy数组相互转化,因此可以直接调用torch.from_numpy(img) 将图像转换成t…...
html+Vue+封装axios实现发送请求
在html中使用Vue和Axios时,可以在HTML中引入Vue库和Axios库,然后使用Vue的语法和指令来创建Vue组件和模板。在Vue组件中,你可以使用Axios发送HTTP请求来获取数据,并将数据绑定到Vue模板中进行展示。 <template><div>&…...
GoogLeNet卷积神经网络输出数据形参分析-笔记
GoogLeNet卷积神经网络输出数据形参分析-笔记 分析结果为: 输入数据形状:[10, 3, 224, 224] 最后输出结果:linear_0 [10, 1] [1024, 1] [1] 子空间执行逻辑 def forward_old(self, x):# 支路1只包含一个1x1卷积p1 F.relu(self.p1_1(x))# 支路2包含 1…...
【docker】dockerfile发布springboot项目
目录 一、实现步骤二、示例 一、实现步骤 1.定义父镜像:FROM java:8 2.定义作者信息:MAINTAINER:learn_docker<https://www.docker.com> 3.将jar包添加到容器:ADD jar包名称.jar app.jar 4.定义容器启动执行命令:…...
利用docker run -v 命令实现使用宿主机中没有的命令
利用docker run -v 命令实现使用宿主机中没有的命令 使用容器中的jar命令解压jar包,并将解压内容输出到挂载在宿主机中的目录里 使用容器中的jar命令解压jar包,并将解压内容输出到挂载在宿主机中的目录里 docker run -it --name java -v /www/temp/java…...
【小沐学NLP】在线AI绘画网站(百度:文心一格)
文章目录 1、简介2、文心一格2.1 功能简介2.2 操作步骤2.3 使用费用2.4 若干示例2.4.1 女孩2.4.2 昙花2.4.3 山水画2.4.4 夜晚2.4.5 古诗2.4.6 二次元2.4.7 帅哥 结语 1、简介 当下,越来越多AI领域前沿技术争相落地,逐步释放出极大的产业价值࿰…...
react经验5:访问子组件内容
应用场景 父级需要调用子组件的某函数 实现步骤 案例:创建自定义按钮 button.tsx import { Ref, forwardRef, useImperativeHandle,ReactNode} from "react" declare type ButtonProps {/**按钮文字 */children?: ReactNode,onClick?: () > voi…...
【LeetCode】647. 回文子串
题目链接 文章目录 1. 思路讲解1.1 方法选择1.2 dp表的创建1.3 状态转移方程1.4 填表顺序 2. 代码实现 1. 思路讲解 1.1 方法选择 这道题我们采用动态规划的解法,倒不是动态规划的解法对于这道题有多好,它并不是最优解。但是,这道题的动态…...
Open3D(C++) 角度制与弧度制的相互转换
目录 一、弧度转角度1、计算公式2、主要函数3、示例代码4、结果展示二、角度转弧度1、计算公式2、主要函数3、示例代码4、结果展示三、归一化到(-PI,PI)1、主要函数<...
【小沐学NLP】在线AI绘画网站(网易云课堂:AI绘画工坊)
文章目录 1、简介1.1 参与方式1.2 模型简介 2、使用费用3、操作步骤3.1 选择模型3.2 输入提示词3.3 调整参数3.4 图片生成 4、测试例子4.1 小狗4.2 蜘蛛侠4.3 人物4.4 龙猫 结语 1、简介 Stable Diffusion是一种强大的图像生成AI,它可以根据输入的文字描述词&#…...
GNN code Tips
1. 重置label取值范围 problem: otherwise occurs IndexError: target out of bounds # reset labels value range, otherwise occurs IndexError: target out of bounds uni_set torch.unique(labels) to_set torch.tensor(list(range(len(uni_set)))) labels_reset label…...
物联网|按键实验---学习I/O的输入及中断的编程|函数说明的格式|如何使用CMSIS的延时|读取通过外部中断实现按键捕获代码的实现及分析-学习笔记(14)
文章目录 通过外部中断实现按键捕获代码的实现及分析Tip1:函数说明的格式Tip2:如何使用CMSIS的延时GetTick函数原型stm32f407_intr_handle.c解析中断处理函数:void EXTI4_IRQHandler 调试流程软件模拟调试 两种代码的比较课后作业: 通过外部中断实现按键捕获代码的实…...
Java对象的前世今生
文章目录 一、创建对象的步骤二、类加载机制三、内存分配指针碰撞 (内存连续)空闲列表 (内存不连续) 四、创建对象的5种方法五、浅拷贝与深拷贝 以下一行代码内部发生了什么? Person person new Person();一、创建对象的步骤 根据JLS中的规定,Java对象…...
Qt中JSON的使用
一.前言: JSON是一种轻量级数据交换格式,常用于客户端和服务端的数据交互,不依赖于编程语言,在很多编程语言中都可以使用JSON,比如C,C,Java,Android,Qt。除了JSON&#x…...
linux安装Tomcat部署jpress教程
yum在线安装: 查看tomcat相关的安装包: [rootRHCE ~]# yum list | grep -i tomcat tomcat.noarch 7.0.76-16.el7_9 updates tomcat-el-2.2-api.noarch 7.0.76-16.el7_9 updat…...
深入理解STM32的PWM:从CubeMX配置到用HAL库精准控制舵机角度(以F103为例)
深入理解STM32的PWM:从CubeMX配置到用HAL库精准控制舵机角度(以F103为例) 在机器人控制、自动化设备等需要精确位置反馈的应用场景中,舵机的精准控制往往是项目成败的关键。许多开发者虽然能够通过PWM实现基本的0、90、180三档控制…...
告别DLL缺失!用VS2019的Setup Project打包C++程序,保姆级配置指南
告别DLL缺失!用VS2019的Setup Project打包C程序,保姆级配置指南 在C开发中,最令人头疼的问题之一莫过于程序在其他电脑上运行时出现"DLL缺失"的错误。这种问题不仅影响用户体验,也让开发者陷入反复调试的困境。本文将带…...
我的第一个CANOpen主站:手把手教你用CanFestival-3源码配置心跳、SYNC和PDO映射
我的第一个CANOpen主站:手把手教你用CanFestival-3源码配置心跳、SYNC和PDO映射 当你第一次面对工业现场总线协议时,那种既兴奋又忐忑的心情我至今记忆犹新。CANOpen作为工业自动化领域的"普通话",其主站开发往往是工程师进阶路上的…...
基于CircuitPython与RP2040打造可编程USB脚踏开关:从硬件到软件的完整指南
1. 项目概述:为什么你需要一个可编程的脚踏开关? 在剪辑视频、处理音频、写代码或者玩游戏的时候,你的双手是不是永远不够用?频繁地在键盘、鼠标、调音台或者剪辑软件的面板之间切换,不仅效率低下,还容易打…...
28V,1.5A,XU1619,升压LED恒流驱动芯片 输入电压:2.5V-5.5V
概述 这是一款恒频电流模式升压转换器,适用于小型、低功耗应用。内部软启动功能可以减少涌入电流。1.2MHz的固定开关频率运行,可以使用小型外部组件。可以在5V电源输入下产生100mA的28V电压。有欠压保护、限流、热过载保护。特点 ●输入电压范围…...
避开CASA模型NPP估算的那些坑:我的IDL代码调试与参数优化心得
避开CASA模型NPP估算的那些坑:我的IDL代码调试与参数优化心得 第一次用CASA模型估算NPP时,我对着屏幕上的异常结果发呆了半小时——明明按照教程一步步操作,为什么输出的NPP值会出现大面积负值?后来才发现,温度胁迫因子…...
Windows安卓驱动安装终极解决方案:一键自动化ADB Fastboot工具
Windows安卓驱动安装终极解决方案:一键自动化ADB Fastboot工具 【免费下载链接】Latest-adb-fastboot-installer-for-windows A Simple Android Driver installer tool for windows (Always installs the latest version) 项目地址: https://gitcode.com/gh_mirro…...
【软考高级架构】案例题考前突击——分布式一致性在互联网金融平台的应用
案例分析题:分布式一致性在互联网金融平台的应用 案例背景 某互联网金融平台为了满足高并发、高可用的业务需求,采用了基于微服务和分布式架构的系统设计。平台核心业务包括账户余额管理、交易流水记录、资金划转等关键模块。 为提升系统性能,架构师引入了如下关键设计:…...
3分钟上手Upscayl:免费AI图像放大工具的终极使用指南
3分钟上手Upscayl:免费AI图像放大工具的终极使用指南 【免费下载链接】upscayl 🆙 Upscayl - #1 Free and Open Source AI Image Upscaler for Linux, MacOS and Windows. 项目地址: https://gitcode.com/GitHub_Trending/up/upscayl 想要将模糊的…...
51单片机计算器DIY:除了加减乘除,你的LCD1602和矩阵键盘还能这样玩?
51单片机计算器进阶指南:解锁LCD1602与矩阵键盘的隐藏玩法 当你在51单片机上成功实现了一个基础计算器后,是否想过这两个核心外设——LCD1602液晶屏和4x4矩阵键盘——还能玩出什么新花样?本文将带你超越简单的加减乘除,探索硬件模…...
