缓存延迟双删的两种策略

策略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 已更新,后续读自然拿到新值)。

相关推荐
2601_9637491044 分钟前
越华环保集团数字化污水治理:端边云采集架构与平台对接实现
java·大数据·架构
xcLeigh1 小时前
Go入门:整数类型的溢出与安全边界
java·安全·golang
源码宝2 小时前
SpringBoot+Vue2 诊所门诊管理系统,完整前后端源码,可直接部署上线
java·源码·his系统·门诊系统·程序代码·诊所系统·门诊his
yychen_java2 小时前
九:Text-to-SQL 智能数据查询与 Human-in-the-Loop 人机协作
java·人工智能·架构
lhldsg3 小时前
智慧场馆解决方案小程序开发实战:从架构设计到部署指南
java·小程序·uni-app
Freak嵌入式3 小时前
Pico UART 数据收发实战:硬件配置、MicroPython 编程
java·开发语言·单片机·嵌入式硬件·生活
devilnumber4 小时前
Oracle 与 MySQL substr 函数差异总结
java·数据库·mysql·oracle
cfm_29144 小时前
线程池阻塞队列
java·开发语言
坐吃山猪4 小时前
【多线程】ThreadPool线程池参数说明
java·网络