Redis缓存一致性:面试官最常挖的坑,3种方案教你完美避雷!

先送福利!2025年最新Java面试宝典,覆盖Redis/Spring/并发/微服务等高频考点:
点击获取网盘资源
(提取码:9b3g)
📌 Redis缓存一致性到底是个啥问题?
每次面试问到Redis缓存,缓存一致性绝对是连环炮的开始。简单说就是:数据库数据变了,但Redis缓存没跟着变,或者变得不对。想象一个场景:用户下单后库存扣减成功,但缓存里的库存还是老数据,结果超卖了!这就是典型的缓存不一致事故现场。
🔍 面试官为啥爱问这个?
因为缓存一致性问题直接暴露你对分布式系统的理解深度!它涉及:
- 数据实时性要求(电商库存 vs 文章阅读数)
- 系统并发承受力(高并发下方案能否扛住?)
- 异常处理能力(更新DB或缓存失败了怎么办?)
💡 三种主流方案PK,哪个更适合你?
方案一:先删缓存,再更新数据库(Cache-Aside)
1. 删Redis缓存
2. 更新MySQL数据库
优点: 逻辑简单,实现快
致命坑:
- 脏数据窗口: 删完缓存后、更新DB前,如果有请求过来,会读到旧DB数据并重新塞回缓存!
- 并发冲突: 多个线程同时删缓存、写DB,顺序错乱可能导致缓存与DB长期不一致。
适用: 对一致性要求不高的场景(比如用户昵称修改)
方案二:先更新数据库,再删缓存(Cache-Aside 改进版)
1. 更新MySQL数据库
2. 删Redis缓存
优点: 比方案一更可靠,脏数据窗口短
依然有雷:
- 删除缓存失败: 如果步骤2失败了,缓存里就是过期旧数据。
- 缓存击穿风险: 缓存删除后,大量请求瞬间压到DB。
解决技巧: - 对删除操作进行重试(用消息队列保证最终一致性)
- 对热点Key设置短暂的缓存空值或使用互斥锁

方案三:订阅数据库变更日志(Binlog/Canal)
1. 更新MySQL ->
2. MySQL写Binlog ->
3. Canal监听Binlog ->
4. 删除/更新Redis缓存
优点:
- 彻底解耦: 业务代码不用关心缓存删除
- 保证最终一致: 基于消息队列重试,可靠性高
缺点: - 架构复杂,需要维护Canal等中间件
- 存在短暂延迟(毫秒级)
🚨 高并发下的保命技巧
- 缓存双删(延时双删):
在方案一/二后,异步等待几秒再删一次缓存,清理可能出现的脏数据。 - 设置缓存过期时间:
哪怕更新失败,旧数据最终也会过期,提供兜底。 - 热点Key加锁:
更新DB和缓存时,对Key加分布式锁,避免并发写入乱序。
❓ 面试时这样答,秒杀90%候选人
面试官: “高并发下如何保证Redis和DB的缓存一致性?”
满分回答:
“首先看业务场景对实时性的要求。如果允许短暂延迟,我会优先选方案二(先更新DB再删缓存)配合消息队列重试。
对于核心数据(如库存),我会加上缓存双删策略:更新DB后立即删一次缓存,再起个异步线程500ms后删第二次。
同时所有缓存Key必须设置合理过期时间兜底。
如果公司有成熟基建,用Binlog监听方案最稳,但要注意同步延迟问题。”
🎁 最后的小贴士
缓存一致性没有银弹!方案选型要结合业务容忍度、系统并发量和团队技术栈。另外多提一句:如果大家需要购买面试鸭会员,可以通过 面试鸭返利网 找我,返利25元,省杯奶茶钱不香吗?

想系统性搞定Redis面试题?强烈建议看看开篇分享的《2025 Java面试宝典》,里面整理了Redis高频题解+实战避坑指南,点击链接直接拿走 👉 https://mianshiyafanli.com


