延迟双删

"延迟双删"是一种 在使用缓存(如 Redis)时保证缓存与数据库一致性 的策略,主要用于解决缓存与数据库之间可能出现的数据不一致问题


一、为什么需要延迟双删?

背景:

在使用缓存时,典型的写流程是:

复制代码
更新数据库 → 删除缓存

高并发下可能会出现脏数据。例如下面这个顺序:

复制代码
线程1 读取缓存(此时缓存存在旧数据)
线程2 更新数据库 + 删除缓存
线程1 把旧数据重新写入缓存(造成脏数据)

最终缓存中保存的仍然是旧数据,数据库是新数据,导致缓存与数据库不一致。


二、延迟双删的核心思想

在第一次删除缓存后,等待一段时间,再删除一次缓存。

流程图:

复制代码
1. 更新数据库
2. 删除缓存(第一次)
3. 休眠一段时间(例如500ms)
4. 再次删除缓存(第二次)

三、延迟双删的流程图示例:

复制代码
用户发起更新请求
        ↓
数据库更新成功
        ↓
第一次删除缓存(此时其他线程如果读到了旧缓存会写回)
        ↓
休眠(等待潜在的写回)
        ↓
第二次删除缓存(把前面写回的旧数据再删掉)

四、代码示例(Java伪代码)

复制代码
public void updateData(String key, Object newData) {
    // 1. 更新数据库
    db.update(key, newData);
    
    // 2. 删除缓存
    redis.del(key);

    // 3. 延迟双删(异步线程中执行)
    new Thread(() -> {
        try {
            Thread.sleep(500); // 500ms 视情况可调
            redis.del(key);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }).start();
}

五、延迟双删适用场景

  • 高并发更新数据 且数据一致性要求高。

  • 热点数据存在并发读写的风险

  • 系统已经在使用 Redis 做缓存,但未引入复杂的缓存一致性机制(如消息队列等)。


六、延迟双删优缺点

✅ 优点:

  • 实现简单

  • 能显著降低缓存脏读的概率

  • 无需引入额外中间件(如MQ)

❌ 缺点:

  • 延迟时间不好设置,可能因业务不同而有偏差

  • 不能百分百解决一致性(极端情况下仍然可能失败)

  • 存在一定的资源浪费(多次删除缓存)


七、与其他方案对比

方案 特点 一致性保障 实现复杂度
先删缓存再更新数据库 不推荐,会有并发写丢失问题 简单
更新数据库后删缓存 普通方案,但有并发问题 简单
延迟双删 在前者基础上改进,容错更强 较好 简单
消息队列同步删除 通过MQ异步删除缓存 更好 中等
缓存一致性中间件(如 Canal + MQ) 高一致性保证 最好 复杂

八、总结

延迟双删是一种简单有效的缓存与数据库一致性保护手段,适用于多数读多写少、并发不是极端高的业务系统。对于大规模分布式场景,可结合 Canal、Binlog、消息队列等更强一致性方案。

相关推荐
咩咩啃树皮6 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
鱟鲥鳚7 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
大模型码小白8 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司9 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地10 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun31415910 小时前
TCP超时重传机制是为了解决什么问题?
java
莫逸风12 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
隔窗听雨眠12 小时前
Spring Boot在云原生时代的编程范式革新研究
spring boot·后端·云原生
z1234567898613 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程
yaoxin52112313 小时前
470. Java 反射 - Member 接口与 AccessFlag
java·开发语言·python