缓存一致性

缓存一致性

   将数据不一致分为三种情况:

           1.数据库有数据,缓存没有数据;

           2.数据库有数据,缓存有数据,数据不相等;

           3.数据库没有数据,缓存有数据。

 缓存策略:Cache Aside Pattern

1.首先尝试从缓存读取,读到数据则直接返回;如果读不到,就读数据库,并将数据写到缓存,并返回。

2.需要更新数据时,先更新数据库,然后把缓存里对应的数据失效掉(删掉)。

读的逻辑很好理解,主要是更新的逻辑。如果不这样做,采用先删除缓存,再更新数据库,会有什么问题呢?  这样做引发的问题是,如果有A、B两个线程同时更新数据,并且A、B已经都做完删除缓存这一步了,接下来A更新数据库,C线程读取数据,没有命中缓存会去数据库中读取A更新的数据并且将数据写到缓存中,这时候B再更新数据库,会导致缓存中的数据和数据库中的不一致,缓存中存在着脏数据,且会一直存在下去。

如果是先更新数据库,然后更新缓存又会引起什么问题呢?如果有A、B两个线程同时做更新数据,A先更新了数据库,B后更新了数据库,则此时数据库中是B的数据,而更新缓存时,确实B先更新缓存,A后更新缓存,则此时缓存中是A的数据,这样缓存和数据库结果又不一致了。

那么是不是Cache Aside这个就不会有并发问题了?不是的,比如一个是读操作,未命中然后就去数据库中读取数据,此时来一个写操作,写完数据后,让缓存失效,然后之前的那个读操作再把老的数据放进去,所以,会造成脏数据。

但,这个case理论上会出现,不过,实际上出现的概率可能非常低,因为这个条件需要发生在读缓存时缓存失效,而且并发有一个写操作。而实际上数据库的写操作会比读操作慢很多,而且还要锁表,而读操作必须在写操作之前进入数据库操作,而又要晚于写操作更新缓存,所有的条件都具备的概率基本不大。

所以,对于缓存一致性,要么通过2PC或者Paxos协议保证一致性,要么就是拼命的降低并发时脏数据概率,具体根据系统对一致性的要求程度。Facebool就是使用了这个降低概率的玩法,因为2PC太慢了,而Paxos协议太复杂。当然最好的就是给缓存设置上过期时间。

现在再看看上面的三种不一致的情况。

1.对于第一种,在读数据的时候,会自动把数据库的数据写到缓存,因此不一致自动消除。

2.对于第二种情况,数据最终变得不一致,但是他们在之前的某个时间点一定是想等的。这种不一致,一定是由于你更新数据所引发的。使用上面的策略,先更新数据库,再删除缓存。不一致的原因除了小概率的读写并发导致,就是数据库更新了,但是删除缓存失败了。

3.对于第三种情况,情况与第二种类似,你把数据库的数据删了,但是删除缓存失败了。

因此,最终的结论是,需要解决的不一致,产生的原因是更新数据库成功,但是删除缓存失败。

解决方案大概有以下几种:

1.对删除缓存进行重试,数据的一致性要求越高,越是重试得快。

2.定期全量更新,简单的说,全部删除再全部加载。

3.给所有缓存一个失效期。

第三种方案可以说是一个大杀器,任何不一致,都可以靠失效期解决,失效期越短,数据一致性越高。但是失效期越短,查数据库就会越频繁。因此失效期应该根据业务来定。

 

 

 

 

 

 

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值