缓存延迟双删的两种策略

策略A:先删 → 更新 DB → 延迟再删(经典版)

复制代码
t1: 请求A 删除缓存
t2: 请求B 查缓存 miss,读到旧值
t3: 请求A 更新 DB 完成
t4: 请求B 把旧值回填缓存  ← 脏数据
t5: 延迟 500ms 后再删缓存  ← 清理 t4 的脏数据

解决的问题: 并发读在"删"和"更新 DB"之间发生,把旧值写回缓存。


策略B:先更新 DB → 删缓存 → 延迟再删

复制代码
t1: 请求A 更新 DB(新值)
t2: 请求B 查缓存 miss,读到新值  ← DB 已经是最新的,直接命中新值
t3: 请求A 删缓存
t4: 延迟 500ms 再删缓存  ← 兜底,防止 t5 回填

解决的问题: 并发读在"更新 DB"之后发生,如果缓存里还有旧值被命中,回填时用新值覆盖即可。但实际上策略 B 里请求 B 读到的就是新值,所以这个策略的"价值"主要体现在:

  • t1-t3 之间如果请求 B 读到了旧缓存值并回填,t5 的第二次删除兜住
  • 某种程度上是冗余的,因为策略 A 里的第一次"删"才是关键

哪个更好?

策略 A(删 → 更新 DB → 延迟删) 策略 B(更新 DB → 删 → 延迟删)
第一次删/写的时机 先删缓存 先更新 DB
并发读期间读到 旧值(但会被延迟删清掉) 新值(因为 DB 已更新)
复杂性 多一次远程 DB 读 更简单,DB 最新就行
实用性 经典方案,解决明确 简化版,依赖"更新 DB 后读到的就是新值"

策略 A 的问题是:并发读在"删缓存"和"更新 DB"之间发生时,读到旧值并回填,需要延迟删来兜底。

策略 B 实际上更简单------只要 DB 更新了,后续的 Cache Aside 读本身就是新值。延迟双删的核心价值在于"先删缓存"这个动作阻断了并发读把旧值写回缓存的路径。


结论

策略 B 在某些场景下是有效的,但策略A 才是延迟双删的标准写法,因为它真正解决了"删和更新之间"的窗口问题。你在看的资料如果是策略 B,可能是在简化实现------但要理解清楚它的前提假设(DB 已更新,后续读自然拿到新值)。

相关推荐
流星白龙7 小时前
【Redis】4.基本全局命令
数据库·redis·缓存
Jelena157795857928 小时前
电商运营分析数据比价接口实战:多平台价格监控与智能决策系统
java·大数据·数据库
神明不懂浪漫9 小时前
【第五章】Java中的继承与多态
java·开发语言
流星白龙10 小时前
【Redis】3.Redis安装与命令行客户端
数据库·redis·缓存
AI多Agent协作实战派11 小时前
AI多Agent协作系统实战(十七):凌晨4点,我的AI系统在“假装工作“——3个bug同时爆炸的5小时
java·前端·bug
gaolei_eit11 小时前
Java+Ai+vue
java·spring·maven
qq_25183645711 小时前
基于java Web 动漫视频网站毕业论文
java·开发语言·前端
LayZhangStrive11 小时前
JUC相关的函数、注解、变量杂记
java·面试·多线程·juc
未秃头的程序猿12 小时前
给公司做了个AI客服Agent,用的Spring AI 1.0,3天上线领导拍板了
java·后端·ai编程
曹牧12 小时前
Eclipse 批量文本替换
java·ide·eclipse