Redis 延迟双删的实现示例

 更新时间:2026年05月08日 08:25:58   作者:哈里谢顿  
延迟双删是在Cache-Aside基础上,为了解决并发读写导致缓存回填旧值问题而设计的方案,本文就来详细的介绍一下Redis 延迟双删的实现示例,感兴趣的可以了解一下

延迟双删(Delayed Double Deletion) 是在 Cache-Aside 基础上,为了解决"并发读写导致缓存回填旧值"问题而设计的方案。

一、问题背景:为什么需要双删?

先看单删的问题场景(先删缓存,再更新DB):

时间点  线程A(写)              线程B(读)
  t1    删除缓存
  t2                            查询缓存(未命中)
  t3                            查询数据库 → 得到旧值
  t4    更新数据库为新值
  t5                            将旧值写入缓存  ← 缓存变脏!

即使你先更新DB再删缓存,也有类似风险:

时间点  线程A(写)              线程B(读)
  t1    更新数据库
  t2                            查询数据库 → 得到旧值(因主从延迟等)
  t3    删除缓存
  t4                            将旧值写入缓存  ← 缓存变脏!

延迟双删的核心思想:等一等,让并发的读请求都结束了,再把缓存清掉。

二、延迟双删的具体步骤

1. 先删除缓存
2. 更新数据库
3. 休眠/等待一段时间(比如 200ms~1s)
4. 再次删除缓存

用代码表示:

import time
def update_with_delayed_double_deletion(key, new_value):
    # 第一次删缓存
    redis.delete(key)
    # 更新数据库
    db.update(key, new_value)
    # 延迟一段时间(关键!)
    time.sleep(0.5)  # 500ms,根据业务调整
    # 第二次删缓存(把可能回填的旧值清掉)
    redis.delete(key)

三、延迟时间怎么定?

这是最关键的参数,定太短没效果,定太长影响性能。

建议公式:

延迟时间 ≈ 主从同步延迟 + 业务读操作耗时 + 冗余缓冲

  • 主从同步延迟:如果有主从架构,通常 100ms~500ms
  • 业务读操作耗时:查询DB + 序列化 + 网络往返
  • 冗余缓冲:再加 100~200ms 保险

实际建议:

  • 无主从:100~300ms
  • 有主从:300~800ms
  • 高并发场景:可以动态调整,或根据监控数据优化

四、第二次删除失败怎么办?

如果第二次删缓存时 Redis 挂了或网络抖动,缓存还是会脏。

解决方案:引入异步重试

import threading
def update_with_retry(key, new_value):
    # 第一次删 + 更新DB
    redis.delete(key)
    db.update(key, new_value)
    # 延迟后异步执行第二次删除
    def delayed_delete():
        time.sleep(0.5)
        try:
            redis.delete(key)
        except Exception:
            # 失败则放入重试队列(MQ 或本地延迟队列)
            retry_queue.put(key)
    threading.Thread(target=delayed_delete).start()

更生产化的做法是用 消息队列延迟任务框架(如 Celery、XXL-Job)来做第二次删除,确保可靠执行。

五、完整流程图

写请求到来
    │
    ▼
┌─────────────┐
│  删除缓存    │◄── 第一次删除,清掉旧值
└─────────────┘
    │
    ▼
┌─────────────┐
│  更新数据库  │
└─────────────┘
    │
    ▼
┌─────────────┐
│  延迟等待    │◄── 等并发读请求结束,旧值回填完成
└─────────────┘
    │
    ▼
┌─────────────┐
│  再次删除缓存 │◄── 第二次删除,清掉可能回填的旧值
│  (带重试)  │
└─────────────┘
    │
    ▼
   结束

六、优缺点总结

优点缺点
实现简单,不引入额外组件延迟等待会阻塞写请求(或用异步)
能有效降低缓存不一致概率延迟时间不好精确估算
兼容现有 Cache-Aside 架构极端高并发下仍可能有小概率不一致

七、适用场景

  • 读多写少:写操作不频繁,延迟等待的开销可接受
  • 允许秒级最终一致:不要求实时强一致
  • 无主从或主从延迟可控:延迟时间能估算得准

八、一句话总结

延迟双删 = "先删缓存 → 更新DB → 等一会儿 → 再删一次",用"等一等"来覆盖并发读回填旧值的时间窗口。

 到此这篇关于Redis 延迟双删的实现示例的文章就介绍到这了,更多相关Redis 延迟双删内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何使用Redis实现电商系统的库存扣减

    如何使用Redis实现电商系统的库存扣减

    在日常开发中有很多地方都有类似扣减库存的操作,本文主要介绍了如何使用Redis实现电商系统的库存扣减,具有一定的参考价值,感兴趣的可以了解一下
    2022-01-01
  • 使用redis分布式锁解决并发线程资源共享问题

    使用redis分布式锁解决并发线程资源共享问题

    这篇文章主要介绍了使用redis分布式锁解决并发线程资源共享问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • 详解redis分布式锁(优化redis分布式锁的过程及Redisson使用)

    详解redis分布式锁(优化redis分布式锁的过程及Redisson使用)

    在分布式的开发中,以电商库存的更新功能进行讲解,在实际的应用中相同功能的消费者是有多个的,这篇文章主要介绍了redis分布式锁详解(优化redis分布式锁的过程及Redisson使用),需要的朋友可以参考下
    2021-11-11
  • Windows操作系统下Redis服务安装图文教程

    Windows操作系统下Redis服务安装图文教程

    这篇文章主要介绍了Windows操作系统下Redis服务安装图文教程,文中给大家提供了redis的下载地址,安装程序步骤,需要的朋友可以参考下
    2018-03-03
  • Redis实现数据的交集、并集、补集的示例

    Redis实现数据的交集、并集、补集的示例

    本文主要介绍了Redis实现数据的交集、并集、补集的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • redis数据结构之压缩列表

    redis数据结构之压缩列表

    这篇文章主要介绍了redis数据结构之压缩列表,压缩列表是列表list和hash数据结构的底层实现之一,是redis为了节约内存而开发的,由一系列特殊编码的连续内存块组成的顺序型数据结构,下面详细内容需要的小伙伴可以参考一下
    2022-03-03
  • Redis7.0部署集群的实现步骤

    Redis7.0部署集群的实现步骤

    本文主要介绍了Redis7.0部署集群的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Redis哨兵模式的实现

    Redis哨兵模式的实现

    Redis的哨兵模式是一种用于自动监控Redis实例状态并在主服务器出现故障时自动切换到从服务器的机制,本文主要介绍了Redis哨兵模式的实现,感兴趣的可以了解一下
    2024-02-02
  • Redis Sentinel实现高可用配置的详细步骤

    Redis Sentinel实现高可用配置的详细步骤

    这篇文章主要介绍了Redis Sentinel实现高可用配置的详细步骤,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • Redis中键值过期操作示例详解

    Redis中键值过期操作示例详解

    这篇文章主要给大家介绍了关于Redis中键值过期操作的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-11-11

最新评论