博主原本以为,《分布式之数据库和缓存双写一致性方案解析》,一文已经十分清晰。然而这一两天,有人在微信上私聊我,以为应该要采用html
先删缓存,再更新数据库,再删缓存数据库
这一方案做为缓存更新策略,而不是先更新数据库,再删缓存。而且搬出了两篇大佬的文章,《Cache Aside Pattern》,《缓存与数据库不一致,咋办?》,但愿博主能加以说明。由于问的人太多了,因此才有了这篇文章的诞生。缓存
在开始这篇文章以前,咱们先本身思考一下如下两个更新策略微信
方案一分布式
(1)删缓存ide
(2)更数据库线程
(3)删缓存htm
方案二blog
(1)更数据库get
(2)删缓存
你们看下面的文章前,本身先思考一下,方案一的步骤(1)有没有存在的必要?
先上一个结论:方案二存在的缺点,方案一所有存在,且方案一比方案二多一个步骤,因此应该选方案二。
下面,针对《Cache Aside Pattern》,《缓存与数据库不一致,咋办?》这两篇文章提出的论点,提出小小的质疑。这两篇文章认为方案二不行的缘由,主要有如下两点
(1)方案二在步骤(2),出现删缓存失败的状况下,会出现数据不一致的情形,以下图所示
Cache Aside Pattern方案存在什么问题?
答:若是先操做数据库,再淘汰缓存,在原子性被破坏时:
(1) 修改数据库成功了
(2) 淘汰缓存失败了
致使,数据库与缓存的数据不一致
(2)方案二存在下面的主从同步,致使cache不一致问题,以下图所示
大体流程就是,线程A写,线程B读,会有如下流程出现
(1)缓存恰好失效
(2)线程A写入master数据库,slave还没同步
(3)线程B发现缓存失效,去slave读到旧值
(4)线程A删除缓存
(5)线程B把旧值放入缓存
然而你们发现了么,这两篇文章提出的反对意见,在该文做者本身所提出的方案一里头也是存在的?
(1)针对删缓存失败问题 方案一的步骤(3)也会可能出现删除缓存失败问题,但是做者没有加以详细说明。
(2)针对数据不一致问题 线程A写,线程B读,会有如下流程出现
(1)线程A删除缓存
(2)线程A写入master数据库,slave还没同步
(3)线程B发现缓存失效,去slave读到旧值
(4)线程A删除缓存
(5)线程B把旧值放入缓存
综上所述,咱们应该选择方案二,而不是方案一。方案二存在的缺点,方案一所有存在,且方案一步骤上多了一步,增长了不稳定因素。
该文章只是纠正了一下目前流传的观点的正确性,并无针对任何人。技术的世界,只论技术。