缓存为什么要延时双删?

首先考虑单删的问题

先删

先删在两个线程的并发下,就可能会出现缓存与数据库数据不一致的问题

先删

后删

后删可以在一定程度上解决两个线程并发下的缓存与mysq不一致的问题

后删

但是在线程数超过两个,达到三个的时候,仍有可能出现数据库数据与缓存数据不一致的问题,无法保证最终一致性,线程A修改数据,删除缓存后,线程B读取数据库数据,放入缓存前,线程C修改了数据,在线程C未删除缓存后,线程B操作缓存写入,导入数据库缓存不一致。
三线程后删问题

延时后删

采用延时后删,在并发场景下,只要延时时间合适,一定可以避免线程B将错误数据加载到缓存中的场景(缓存删除前一直读缓存数据,缓存删除后,读事务提交后的数据,出现后删中三线程并发下的缓存与mysql数据不一致场景的可能性不大),可以保证最终一致性,但是在延时删除期间,线程B会长时间读取到旧数据,这在一些场景下无法接受的。

延时后删

接着考虑双删

双删

仅仅双删,在两个线程并发的场景下,就无法保证缓存与mysql的最终一致性

双删

延时双删

伪代码
public void 延时双删{
    // 减少延后删除导致的其他线程读取老数据的尝尽出现。
    delCache(key);
    updateMysql(data);
    // 解决缓存与mysql无法保证最终一致性的问题。
    sleep(time);
    delCaChe(key)
}
极端场景

极端情况下,延时双删,也无法避免某个线程长时间读取老数据的问题,但是通常删除缓存与更新数据库操作的间隔比较短,所以出现这种场景的概率不是很大。

延时双删极端场景

总结

采用延时双删,是为了在保证数据库与缓存数据最终一致性的情况下,尽可能的减少查询老数据场景出现的可能性。

### 大厂不采用延时的原因 在实际应用中,尽管延时可以有效减少缓存击穿等问题带来的影响,但在大多数情况下并未被广泛采纳。主要原因在于这种策略会增加系统的复杂性和维护成本[^1]。 #### 系统复杂性的提升 引入延时意味着需要额外设计一套机制来处理延迟操作以及确保两次除动作的一致性。这不仅涉及到更复杂的业务逻辑实现,还需要对现有架构做出调整,从而提高了整个系统的开发难度和技术门槛。 #### 维护成本上升 随着功能模块数量的增长,长期来看将会显著提高后期运维的成本。每一次变更都需要更加谨慎地评估其可能引发的风险,并且当出现问题时排查起来也会变得更加困难。 #### 性能开销增大 为了支持延时特性,通常需要占用更多的计算资源用于定时任务调度、状态管理等方面的工作,进而可能导致整体性能有所下降。特别是在高并发环境下,这样的性能损失可能会变得尤为明显。 因此,在面对具体问题时应优先考虑简化方案而非盲目追求所谓的最优解法。对于绝大多数应用场景而言,通过合理配置缓存的有效期并结合其他有效的防护措施已经能够很好地满足需求[^4]。 ```python import time def update_data_with_cache_invalidation(data_id, new_value): # 更新数据库中的记录 db.update({'id': data_id}, {'value': new_value}) # 除对应的数据缓存条目 cache.delete(f"data:{data_id}") # 防止再次查询到旧版本的缓存数据 return "Data updated and cache invalidated." ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值