首页 > 数据库 > 文库 > 正文

深入理解分布式之数据库和缓存双写一致性方案剖析

2022-07-20 12:35:51
字体:
来源:转载
供稿:网友
  为什么写这篇文章?
  首先,缓存由于其高并发和高性能的特性,已经在项目中被广泛使用。在读取缓存方面,大家没啥疑问,都是按照下图的流程来进行业务操作。
  深入理解分布式之数据库和缓存双写一致性方案解析cdn2.b0.upaiyun.com/2018/05/efb54ba1306999e884c5f44d35db7380.png">
  但是在更新缓存方面,对于更新完数据库,是更新缓存呢,还是删除缓存。又或者是先删除缓存,再更新数据库,其实大家存在很大的争议。目前没有一篇全面的博客,对这几种方案进行解析。于是博主战战兢兢,顶着被大家喷的风险,写了这篇文章。
 
  同时有请求A和请求B进行更新操作,那么会出现
  (1)线程A更新了数据库
  (2)线程B更新了数据库
  (3)线程B更新了缓存
  (4)线程A更新了缓存
  这就出现请求A更新缓存应该比请求B更新缓存早才对,但是因为网络等原因,B却比A更早更新了缓存。这就导致了脏数据,因此不考虑。
  原因二(业务场景角度)
  有如下两点:
  (1)如果你是一个写数据库场景比较多,而读数据场景比较少的业务需求,采用这种方案就会导致,数据压根还没读到,缓存就被频繁的更新,浪费性能。
  (2)如果你写入数据库的值,并不是直接写入缓存的,而是要经过一系列复杂的计算再写入缓存。那么,每次写入数据库后,都再次计算写入缓存的值,无疑是浪费性能的。显然,删除缓存更为适合。
 
  接下来讨论的就是争议最大的,先删缓存,再更新数据库。还是先更新数据库,再删缓存的问题。
 
 
  (2)先删缓存,再更新数据库
  该方案会导致不一致的原因是。同时有一个请求A进行更新操作,另一个请求B进行查询操作。那么会出现如下情形:
  (1)请求A进行写操作,删除缓存
  (2)请求B查询发现缓存不存在
  (3)请求B去数据库查询得到旧值
  (4)请求B将旧值写入缓存
  (5)请求A将新值写入数据库
  上述情况就会导致不一致的情形出现。而且,如果不采用给缓存设置过期时间策略,该数据永远都是脏数据。
  那么, 如何解决呢?采用延时双删策略。

(编辑:错新网)

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选