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

Posted _瞳孔

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库面试题——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为空,有请求进来时,便会去访问数据库,此时数据库中的数据已是更新后的数据,保证了数据的一致性。

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

创作打卡挑战赛 赢取流量/现金/CSDN周边激励大奖

以上是关于数据库面试题——redis缓存主动更新策略(延时双删)的主要内容,如果未能解决你的问题,请参考以下文章

Redis缓存一致性

数据库面试题——redis中key没有设置过期时间但被redis主动删除(8种内存淘汰策略)

如何保证Redis缓存与数据库的一致性?

redis 常见的面试题,既是面试题也是知识点

字节跳动java面试题,附详细答案解析

Redis7高级之缓存双写一致性之更新策略探讨