尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Java面试中Redis缓存一致性怎么答?

Java面试中Redis缓存一致性怎么答? 面试官问缓存一致性不是想听你背“先删缓存再更新数据库”或者“先更新数据库再删缓存”这两句话。他想知道的是你知不知道这两种顺序在并发场景下分别会出什么问题以及你实际项目里怎么选、怎么兜底。先更新数据库再删除缓存——这是最常用的方案Cache Aside Pattern读的时候先读缓存没有就读数据库然后回写缓存写的时候先更新数据库再删除缓存。为什么是删除而不是更新因为更新缓存可能写入一个过期的值。比如两个并发写请求A先更新数据库为1B后更新数据库为2但B先删缓存A后删缓存缓存里最终是空下次读会从数据库加载2没问题。但如果A更新缓存为1B更新缓存为2顺序一乱缓存里可能留下1数据库是2数据就不一致了。删除缓存相当于让缓存失效下次读自然从数据库加载最新值。这个方案简单大多数场景够用。但它不是没有漏洞。并发读写的经典漏洞先更新DB再删缓存也会不一致假设线程A读数据缓存刚好失效A去查数据库拿到旧值10。此时线程B写数据更新数据库为20然后删除缓存。A拿着旧值10回来把10写进缓存。结果缓存里是10数据库里是20不一致了。这个场景发生概率不高因为读操作通常比写操作快且要求A在查数据库和写缓存之间B完成了更新和删除。但概率低不代表不会发生。解决办法是延迟双删更新数据库后删一次缓存隔几百毫秒再删一次。第二次删除是为了把并发读可能回写的旧值清掉。延迟时间怎么定一般设成读业务耗时加几百毫秒比如500ms到1秒。但延迟双删会阻塞写请求影响吞吐。更可靠的方案订阅binlog异步删除用Canal监听MySQL的binlog数据库一有变更就发消息去删Redis缓存。这样业务代码不用管缓存删除数据库和缓存彻底解耦。缺点是架构复杂了多了一个Canal中间件还要处理消息丢失和重复消费。但它是最终一致性的经典落地方式很多大厂在用。强一致性能不能做到很难。Redis和MySQL是两个系统没有分布式事务强一致性代价极高。除非用分布式锁把读写串行化但性能直接崩掉。所以面试时要说清楚缓存一致性追求的是最终一致性不是强一致性。业务能容忍短暂不一致比如几秒内看到的还是旧数据那上述方案都够用。如果业务要求强一致比如支付金额那就不该用缓存直接读数据库。面试怎么答才出彩先讲Cache Aside Pattern说明为什么删缓存而不是更新缓存。然后主动抛出并发漏洞展示你知道先更新DB再删缓存也有问题。接着给延迟双删说清楚它的原理和代价。最后提binlog订阅表示你了解更可靠的异步方案。如果能补一句“具体选哪个看业务容忍度强一致场景不用缓存”面试官会觉得你不仅懂技术还懂取舍。别忘了兜底过期时间和版本号无论用哪种方案缓存都要设过期时间。这是最后一道防线万一删缓存失败过期后也能自动纠正。还可以在缓存value里塞版本号或时间戳读的时候比对数据库版本不一致就强制刷新。这些细节说出来比背八股文有说服力。缓存一致性没有银弹只有权衡。面试官想听的不是标准答案是你思考的过程知道问题在哪知道方案代价知道业务边界。答到这一层这道题就稳了。
返回列表