1. Redis缓存一致性问题背景
在分布式系统中,缓存与数据库的数据一致性是个经典难题。我经历过一个电商促销系统,高峰期每秒上万次查询请求打到商品详情页,当时采用经典的Cache-Aside模式(先读缓存,未命中再查库),结果因为双写不一致导致超卖事故。那次教训让我深刻认识到:缓存更新不是简单的"删了再写"就能解决的。
延迟双删策略(Delayed Double Delete)正是在这种背景下被广泛讨论的方案。它的核心思想是在数据库更新操作前后各执行一次缓存删除,并在两次删除之间加入短暂延迟。但很多人把它当银弹,却忽略了它的适用边界——去年我们系统从MySQL迁移到TiDB时就踩过坑,同样的双删逻辑在新环境下出现了更严重的数据不一致。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 延迟双删的工作原理
2.1 基本执行流程
典型的延迟双删包含以下步骤:
- 首次删除:在数据库事务开始前删除缓存
- 数据库操作:执行实际的数据更新(insert/update/delete)
- 延迟等待:暂停100-500ms(具体时长需根据系统负载测算)
- 二次删除:再次删除缓存
java复制// 伪代码示例
public void updateProduct(Product product) {
// 第一次删除
redis.del("product:" + product.id);
// 数据库更新
db.update(product);
// 延迟等待(建议用线程休眠而非定时任务)
Thread.sleep(calculateDelayTime());
// 第二次删除
redis.del("product:" + product.id);
}
2.2 解决的核心问题
这种设计主要应对两种场景:
- 并发写竞争:当两个写操作同时发生时,防止因操作时序问题导致脏数据残留
- 主从延迟:在读写分离架构中,避免从库未同步时读到旧数据
关键点:第二次删除前的延迟必须大于主从同步耗时 + 缓存读取耗时。我们在MySQL主从架构中实测发现,这个值通常需要设置在200ms以上才能覆盖99%的请求。
