数据库面试题——redis缓存主动更新策略(延时双删)

在这里插入图片描述
对于内存淘汰和超时剔除,可见我的另一篇博客:数据库面试题——redis中key没有设置过期时间但被redis主动删除(8种内存淘汰策略)

这篇博客主要讲主动更新,主动更新策略有三种:

  • Cache Aside Pattern:由缓存的调用者在更新数据库的同时更新缓存,这种方法需编程实现,业务比较复杂
  • Read/Write Through Pattern:缓存与数据库整合为一个服务,由服务来维护一致性。调用者调用该服务,无需关心缓存一致性问题。这个方法最大的问题就是维护这样一个服务比较复杂,当前市面上没有完善的解决方案
  • Write Behind Caching Pattern:调用者只操作缓存,由其它线程异步的将缓存数据持久化到数据库,保证最终一致。如果异步线程还没有将最新操作持久化到数据库中redis就宕机了,会导致数据丢失

其中Cache Aside Pattern是最受欢迎的更新策略,但操作缓存和数据库时有三个问题需要考虑:

删除缓存还是更新缓存?

更新缓存:每次更新数据库都更新缓存,无效写操作较多
删除缓存:更新数据库时让缓存失效,查询时再更新缓存

因此开发中一般采用删除缓存的方式

如何保证缓存与数据库的操作的同时成功或失败?

单体系统:将缓存与数据库操作放在一个事务
分布式系统:利用TCC等分布式事务方案

先操作缓存还是先操作数据库?

先删除缓存,再操作数据库
先操作数据库,再删除缓存

可以先对这两种方案进行对比

先删除缓存,再操作数据库可能会导致下图问题,就是当线程1删除缓存后,还没有更新完数据库,线程2就来查询,发现redis没有,就去查询数据库,将脏数据写入缓存,这将导致后续所有访问都是获取redis脏数据
在这里插入图片描述
先操作数据库,再删除缓存可能导致下图问题,假如某数据没有缓存,线程1就去数据库读取数据,在它尚未将其写入redis的时候,线程2更新了数据库,然后在线程1还没有将旧数据写入redis的时候执行了删除缓存操作,这当然是无效删除,然后线程1再将旧数据写入redis,这也会导致后续的所有请求都拿到脏数据
在这里插入图片描述
可见无论是先删后写还是先写后删都有可能导致脏数据的产生,因此出现了第三种解决方案,也就是延时双删

延时双删方案执行步骤

  1. 删除缓存
  2. 更新数据库
  3. 延时500毫秒
  4. 删除缓存

为何要延时500毫秒:这是为了我们在第二次删除redis之前能完成数据库的更新操作。假象一下,如果没有第三步操作时,有很大概率,在两次删除redis操作执行完毕之后,数据库的数据还没有更新,此时若有请求访问数据,便会出现我们一开始提到的那个问题。

为何要两次删除缓存:如果我们没有第二次删除操作,此时有请求访问数据,有可能是访问的之前未做修改的redis数据,删除操作执行后,redis为空,有请求进来时,便会去访问数据库,此时数据库中的数据已是更新后的数据,保证了数据的一致性。

如果有兴趣了解更多相关内容,欢迎来我的个人网站看看:瞳孔的个人空间

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值