延迟双删

"延迟双删"是一种 在使用缓存(如 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、消息队列等更强一致性方案。

相关推荐
User_芊芊君子3 分钟前
【Java】设计模式——单例、工厂、代理模式
java·设计模式·代理模式
2301_8035545212 分钟前
正向代理,反向代理,负载均衡还有nginx
java·nginx·负载均衡
要开心吖ZSH14 分钟前
软件设计师备考-(十六)数据结构及算法应用(重要)
java·数据结构·算法·软考·软件设计师
向上的车轮22 分钟前
基于Java Spring Boot的云原生TodoList Demo 项目,验证云原生核心特性
java·spring boot·云原生
程序员清风24 分钟前
快手一面:为什么要求用Static来修饰ThreadLocal变量?
java·后端·面试
逍遥德24 分钟前
Java8 Comparator接口 和 List Steam 排序使用案例
java·spring boot·list·排序算法
前行的小黑炭43 分钟前
Android :如何快速让布局适配手机和平板?
android·java·kotlin
_BugMan2 小时前
【IDEA】干活?一个IDEA即可,集成开发平台打造攻略
java·ide·intellij-idea
YA3333 小时前
java设计模式二、工厂
java·开发语言·设计模式
金色天际线-3 小时前
Nginx 优化与防盗链配置指南
java·后端·spring