【搞定面试官】系列:如何保证缓存与数据库的双写一致性

缓存三连问:项目中如何使用、为什么要使用、使用不当会造成什么后果? 问题 项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果? 分析 这个问题,互联网公司必问,要是一个人连缓存都不太清楚,那确实比较尴尬。 只要问到缓存,上来第一个问题,肯定是先问问你项目哪里用了缓存?为啥要用?不用行不行?如果用了以后可能会有什么不良的后果? 这就是看看你对缓存这个东西背后有没有思考,如果你就是傻乎乎的瞎用,没法给面试官一个合理的解答,那面试官对你印象肯定不太好,觉得你平时思考太少,就知道干活儿。 面试题剖析 项目中缓存是如何使用的? 这个,需要结合自己项目的 阅读详情

面试开始

小伙子你好,看你简历上写到了MySQL和Redis。今天我们就围绕他们两个展开吧。Redis和MySQL是后端开发中举重若轻的重要角色。实际开发中二者也基本上如影随行,为了提高性能和响应,Redis常常存放热点数据,MySQL存放所有数据,保证数据持久化。所以Redis可以说是MySQL的一部分数据。

那么问题来了,当MySQL中的持久化数据发生改变,如何通知Redis呢?也即如何保证缓存和数据库数据的双写一致性呢?

面试官您好,我们在开发中采取的方案是:先更新数据库,然后删除相应缓存,直到下次请求缓存发现没有数据,再从MySQL中读取,同时将数据更新到Redis。

那为什么采用删除缓存而不是更新缓存呢?

如下图所示,如果采取更新缓存的方式,可能出现请求A先于请求B发生,更新缓存应该比请求B更新缓存早才对,但是因为网络等原因,B却比A更早更新了缓存,这就导致了脏数据。
在这里插入图片描述

其次,如果你是一个写数据库场景比较多,而读数据场景比较少的业务需求,采用更新缓存的方案就会导致数据压根还没被读取过,但缓存已被频繁的更新,浪费性能。

那先删除缓存,再更新数据库会不会有什么问题?

如下图所示,请求A进行写操作,删除缓存,请求B查询发现缓存不存在,就去数据库查询得到旧值,之后将旧值写入缓存,此时请求A再将新值写入数据库。
这种情况就会导致数据不一致的情形出现。而且,如果不采用给缓存设置过期时间策略,该缓存数据永远都是脏数据。
在这里插入图片描述

好的,刚刚说的方案确实在并发环境中都会有问题。那你们采用先更新数据库,再删除缓存,这种方案一定不会出现并发问题吗?

答案是不一定,也可能会出现并发问题。如下图所示,
当步骤Step3的更新数据库操作比步骤Step2的读取数据库操作耗时更短,就有可能使得步骤Step4先于步骤Step5,此时缓存中的就是脏数据。但一般情况下数据库的读操作的速度是远快于写操作的(此点从MySQL的并发读写量就可看出,相同硬件配置下并发读的效率是并发写的数倍)。
在这里插入图片描述

因此,如果你想实现基础的缓存和数据库双写一致的逻辑,那么在大多数情况下,在不想做过多设计、增加太大工作量的情况下,请先更新数据库,再删除缓存!

先更新数据库,再删除缓存,除了你刚刚说得问题,还会有别的问题吗?

如果MySQL采用了读写分离架构,当请求A更新数据在master库上并删除了缓存,但此时数据库主从同步还未完成。请求B查询缓存发生Cache miss之后从slave库上读取到的还是旧值,此时也会造成数据不一致。
在这里插入图片描述

你刚刚说到先更新数据库,再删除缓存也有可能造成数据不一致,怎么解决呢?

采用延时双删。如下图所示,请求A更新数据库之后,为防止删除缓存先行发生于请求B的将缓存写入旧值,可以通过将请求A更新完数据库之后休眠一会(例如100ms,200ms,根据实际业务场景拟定),再删除缓存,这样基本能保证缓存中存放的不会是脏数据。主从架构也是这个原理,就是请求A在更新master之后不用立即删除缓存,通过延时双删保证主从同步已经完成,最后删除缓存数据。
在这里插入图片描述

但你这种方案,请求A休眠一段时间的话,可能会影响到接口的RT,降低系统的吞吐量,如何解决呢?

这里比较优雅的方案是通过异步实现。即开启一个线程池,在请求A的时候开启一个单独的线程,异步的休眠一段时间然后执行缓存删除。当然也可以通过将缓存中相应的key扔到消息队列,通过MQ异步删除,但仅为了异步删除缓存就多加了一层消息队列,可能会造成系统设计更加复杂,并且会带来别的问题。

前面一直有提到删除缓存,如果删除缓存失败了怎么办呢?

再加一个重试机制,保证删除缓存成功。

如果我一定要数据库和缓存数据一致性怎么办?

没有办法做到绝对的一致性,这是由CAP理论决定的,缓存系统适用的场景就是非强一致性的场景,所以它属于CAP中的AP。

CAP理论是分布式系统中的经典理论,即一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。

根据BASE(Basically Available,Soft State和Eventually Consistent)理论,缓存和数据库只能做到数据的最终一致性。

面试结束

时间也不早了,今天就到这里吧,看出来小伙子对这块掌握的比较深入。我们公司就缺少你这种人才,要不现在就签把Offer签了吧。
这个时候你肯定欲绝还迎,一手接Offer一边摆摆手:不行不行,深圳马那边也急着等我给回复呢,催了我好几天了。
面试官一听,payroll组何在,加价!

小结

使用缓存并不是一个很简单的事情,尤其在需要缓存与数据库保持强一致的场景,才知道让数据库数据和缓存数据保持一致性是一门很高深的学问。
从远古的硬件缓存,操作系统缓存开始,缓存就是一门独特的学问。这个问题也被业界探讨了非常久,争论至今也无果,因为其实这是一个权衡的问题。
我是少侠露飞,爱技术,爱分享。

MOS管关断时尖峰电压的5种实用抑制方案(附实测数据对比) 本文针对MOS管关断时产生的尖峰电压问题,提供了五种经过实验室实测验证的实用抑制方案。文章从尖峰电压的成因分析入手,详细阐述了优化PCB布局、设计RC缓冲电路、选用TVS二极管钳位、调节驱动电路以及使用磁珠吸收高频振荡等方法的原理、实施步骤与实测数据对比,为硬件工程师解决开关电源和电机驱动中的过压应力与EMI问题提供了系统性的实战指南。 阅读详情

相关推荐

从婴儿学步到工业级应用:VLA的‘隐式标定‘原理通俗图解

本文深入解析VLA(Vision-Language-Action)模型的'隐式标定'原理,通过类比婴儿学习机制,揭示其如何替代传统手眼标定技术。文章对比了工业机器人传统标定与VLA数据驱动方法的差异,并可视化神经网络注意力机制,展示其在空间关系编码上的突破性进展。最后探讨了VLA在工业应用中的优势与混合架构解决方案。

pz890123456的博客 324

缓存与数据库一致性问题深度剖析

前言 本篇文章是我之前系列文章中的一篇,主要讨论了我们在平时的开发过程中,各大系统中都要用到的缓存数据的问题,进一步延伸到数据库和缓存的双写一致性问题,并且给出了所有方案的实现代码方便大家参考。 本篇文章主要内容 数据缓存 为何要使用缓存 哪类数据适合缓存 缓存的利与弊 如何保证缓存和数据库一致性 不更新缓存,而是删除缓存 先操作缓存,还是先操作数据库 非要保证数据库和缓存数据强一致该怎么办 缓存和数据库一致性实战 实战:先删除缓存,再更新数据库 实战:先更新数据库,再删缓存 实战:缓存延时

蛮三刀酱 1349

YALMIP介绍及怎么在Matlab中加YALMIP、SDPT3

目录YALMIP简介怎么在Matlab中加YALMIP?1. 创建决策变量:2. 添加约束:3. 参数配置4. 求解怎么在MatlabR2019a中加YALMIP?1.下载工具包2.放置工具包3.添加路径4.测试安装结果怎么在MatlabR2019a中加SDPT3? YALMIP简介 怎么在Matlab中加YALMIP? yalmip是一位“集大成者”,它不仅自己包含基本的线性规划求解算法,比如linprog(线性规划)、bintprog(二值线性规划)、bnb(分支界定算法)等,他还提供了对cpl

m0_51431440的博客 2万+

先删除缓存再修改数据库数据和先修改数据库数据再删除缓存的两种方法,以及其中消息队列的使用分析

在一个完整的服务器应用程序中,包含数据库、消息队列和缓存,修改数据的操作的确需要一些考虑。通常,缓存和数据库之间的操作顺序会影响应用程序的性能和数据的一致性。

qq_52695936的博客 728

PRIDE数据库20年:2025更新

PRoteomics IDEntifications (PRIDE)数据库(https://www.ebi.ac.uk/pride/)是全球领先的基于质谱(MS)的蛋白质组学数据存储库,也是ProteomeXchange联盟的创始成员之一。本文总结了过去3年中PRIDE资源及相关工具的发展情况。提交到PRIDE存档的数据集数量平均每月达到约534个。主要得益于基础设施的持续改进,如用于超大数据集的新文件传输协议(Globus)、新的数据重新提交流程以及自动数据集验证过程。

多组・学・多组学 2063

边缘设备选型指南:从数据采集到AI推理,工业物联网硬件如何匹配你的需求?

本文提供了一份全面的工业物联网边缘设备选型指南,系统性地阐述了如何根据数据采集、协议兼容性、边缘AI推理算力及环境适应性等核心需求匹配硬件。文章深入剖析了从CPU/GPU/NPU选择到MQTT、Sparkplug B等工业协议支持的实战考量,并强调了软件生态与全生命周期成本的重要性,旨在帮助项目负责人在复杂场景中做出明智决策。

weixin_29168813的博客 88

使用缓存时,先操作数据库 or 先操作缓存

使用缓存时,先操作数据库 or 先操作缓存?谈谈你的见解。如何上面是一道面试题,你要如何回答,一个去团团面试的同学回来告诉我,一个问题带出一串问题,回答不好,直接作废,换句话说,刷面试题的同学要注意了,要一串一串的刷,把相关连的问题串起来,如果只是单个问题,你会很快暴露。在使用缓存的场景中,先操作数据库还是先操作缓存取决于具体的业务需求和性能目标。假如有两个并发的请求,一个写请求,一个读请求,流程如下:可能存在的脏数据时间范围:更新数据库后,失效缓存前。这个时间范围很小,通常不会超过几毫秒。

威哥爱编程,华为 HDE,鸿蒙极客、优快云博客专家、《鸿蒙 HarmonyOS 5/6 开发之路》系列图书第一作者 2095

Ubuntu22环境下Xinference与RAGFLOW集成:构建高效rerank模型服务【实战指南】

本文详细介绍了在Ubuntu22.04系统上,通过部署Xinference模型推理服务来加载bge-reranker-base等rerank模型,并将其与RAGFLOW框架集成的完整实战指南。该方案实现了模型服务的解耦与灵活管理,有效提升RAG系统的检索精度与答案相关性,并提供了从环境配置、服务启动、网络连接到性能调优及常见问题排查的全流程解决方案。

pluto的博客 500

Redis(三)- 缓存问题

Redis 搞定缓存问题

Eriksen的博客 1888

AutoLisp文件(.lsp)从编写到加载运行:一份给CAD新手的避坑指南

本文为CAD新手提供了一份AutoLisp文件(.lsp)从编写到加载运行的完整指南,涵盖编写环境配置、文件加载流程、调试技巧及工程化实践建议。通过详细的步骤和常见错误解决方案,帮助用户避免常见陷阱,提升AutoLisp脚本的开发效率和应用效果。

weixin_29228203的博客 896

Unity WebView 插件⭐️(十八)3D WebView 原生2D模式 — Native 2D Mode

Unity中的 浏览器插件:3D WebView,利用好该插件我们可以自己使用Unity打造出一个自定义的多样化浏览器。可以用于2D显示,也可以用于3D空间场景中使用,在PC端、手机端和VR设备等都可以有一个非常好的效果。一起来浏览器插件:3D WebView的专栏学习使用吧!

努力前行,总会成为自己心中的那道光 7640

缓存更新和数据库更新先后顺序

1、更新缓存,更新数据库谁先操作都可能发生 问题:并发写操作A、B时,由于无法保证时序 1)可能出现请求A先更新缓存,B后更新数据库 2)B更新缓存时,A更新了数据库 3)导致数据库和缓存数据不一致 ...

weixin_43361136的博客 3107

Altair HyperWorks软件二次开发:二次开发成果展示与报告撰写

HyperMesh Python API允许用户通过Python脚本控制HyperMesh的大部分功能,包括模型创建、修改和分析。它提供了丰富的函数库,可以处理节点、元素、材料属性、载荷和边界条件等。二次开发可以用于创建自定义工具,这些工具可以集成到HyperWorks中,提供特定的功能或简化复杂的操作。

kkchenjj的博客 1639

大厂面试官喜欢这样问Redis,双写一致性、并发竞争、线程模型,我整理好了

你知道的越多,你不知道的越多 点赞再看,养成习惯 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行360°的刁难。作为一个在互联网公司面一次拿一次offer的面霸(请允许我使用一下夸张的修辞手法),打败了无数竞争对手,每次都只能看到无数落寞的身影失望的离开,略感愧疚,在一个寂寞难耐的夜晚,我痛定思痛,决定开始写《吊...

敖丙 3万+

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

今天面试官问我:为什么在系统中不推荐双写?因为我老大砍我QAQ~

引言 某日,阿雄跑去面试!于是有如下情形 面试官:“阿雄是吧,做做自我介绍!” 阿 雄:“我叫阿雄,来自某a国际电商公司!” 面试官:“我看你项目里用了elasticsearch,你是怎么同步数据的呢?” 阿 雄:“在代码里写入数据库的时候,同时再写入elasticsearch!” 面试官:“那你如何保证写入数据库,和写入elasticsearch原子性问题呢?万一写入数据库成功了,写入elasticsearch失败了怎么处理?” 阿 雄:“我还是回去等通知吧!” OK,以上情形纯属虚构,如有雷同,绝

a646705816的博客 8607

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

面试官:为什么在系统中不推荐双写?

引言 某日,阿雄跑去面试!于是有如下情形 面试官:"阿雄是吧,做做自我介绍!"阿 雄:"我叫阿雄,来自某a国际电商公司!" 面试官:"我看你项目里用了elasticsearch,你是怎么同步数据的呢?" 阿 雄:"在代码里写入数据库的时候,同时再写入elasticsearch!" 面试官:"那你如何保证写入数据库,和写入elasticsearch原子性问题呢?万一写入数据库成功了,写入elasticsearch失败了怎么处理?" 阿 雄:"我还是回去等通知吧!" OK,以上情形纯属虚构,如...

勇往直前的专栏 589

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

面试官: 为什么在系统中不推荐双写?

点击上方“芋道源码”,选择“设为星标”管她前浪,还是后浪?能浪的浪,才是好浪!每天 8:55 更新文章,每天掉亿点点头发...源码精品专栏原创 | Java 2020 超神之路,很肝~中...

芋艿V 107

面试官:缓存一致性问题怎么解决?

关于Redis的其他的一些面试问题已经写过了,比如常见的缓存穿透、雪崩、击穿、热点的问题,但是还有一个比较麻烦的问题就是如何保证缓存一致性。对于缓存和数据库的操作,主要有以下两种方式。 ...

程序IT圈 102

数据一致性,为什么不推荐双写?

往期热门文章:1、Spring Boot实现抽奖大转盘 2、Logback这样配置,性能提升10倍! 3、还在用策略模式解决 if-else?Map+函数式接口方法才是YYDS! 4、My...

Java后端技术 481

面试官:为什么在系统中不推荐双写?

引言某日,阿雄跑去面试!于是有如下情形 面试官:"阿雄是吧,做做自我介绍!"阿 雄:"我叫阿雄,来自某a国际电商公司!"面试官:"我看你项目里用...

陈树义 169

Redis双写一致性、并发竞争、线程模型

Redis双写一致性、并发竞争、线程模型 你知道的越多,你不知道的越多 点赞再看,养成习惯https://github.com/java…已经开源,有面试脑图 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在Redis的使用和原理方面对小伙伴们进行360°的刁难。作为一个在互联网公司面一次拿一次offer的面霸(请允许我使用一下夸张的修辞手法),打败了无数...

cxu123321的博客 366

为什么在系统中不推荐双写?

往期热门文章:1、《往期精选优秀博文都在这里了!》2、Thread.sleep(0) 到底有什么用?3、为什么阿里规定需要在事务注解 @Transactional 中指定 rollbac...

Java后端技术 827

web前端高频面试题:如何保证Redis缓存与数据库的同步?

如果我们先删Redis再写数据库,写线程上来把Redis删了,读线程立即读数据库,比如读到的旧数据是8,然后写线程再改数据库为9,这时数据库最新为9,但Redis中的值是8,结果还是不一致。其实缓存的实现思路很简单,这个思路能保证只有第一次查询的是数据库,后续的访问查询的都是Redis,这样不仅提高了接口的访问效率,还在一定程度上实现了数据库的读写分离。先写数据库,再更新Redis,上图中演示了一种极端情况,按照时间轴的发展,数据库里的最新值是8,但Redis中的最新值是9,并没有一致。

威哥爱编程,华为 HDE,鸿蒙极客、优快云博客专家、《鸿蒙 HarmonyOS 5/6 开发之路》系列图书第一作者 1300

缓存——项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果?

问题 项目中缓存是如何使用的?为什么要用缓存?缓存使用不当会造成什么后果? 分析 这个问题,互联网公司必问,要是一个人连缓存都不太清楚,那确实比较尴尬。 只要问到缓存,上来第一个问题,肯定是先问问你项目哪里用了缓存?为啥要用?不用行不行?如果用了以后可能会有什么不良的后果? 这就是看看你对缓存这个东西背后有没有思考,如果你就是傻乎乎的瞎用,没法给面试官一个合理的解答,那面试官对你印象肯定...

一棵大树 1万+
上一篇: 【Java基础】Integer的自动拆箱和享元模式,这次我学到了
下一篇: 【享学MySQL】系列:MySQL索引的数据结构,索引种类及聚簇索引和非聚簇索引
少侠露飞
博客等级 码龄9年 214粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值