redis缓存与数据库的一致性问题

详细链接:
https://blog.kido.site/2018/11/24/db-and-cache-preface/
https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651959442&idx=1&sn=feb8ff75385d8031386e120ef3535329&scene=21#wechat_redirect

耗子叔的解决方案:https://coolshell.cn/articles/17416.html

即采用先更新数据库,更新成功后,再删除缓存的防止,防止后续缓存和数据库中数据不一致的情况。

考虑一下先删除缓存,再更新数据库会发生什么情况?两个并发操作,更新和查询操作,更新操作删除完缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的数据是脏的,而且还一直这样脏下去了。

而先更新数据库,再删除缓存,可能会有短暂的不一致的情况,但是不会造成后续缓存不一致情况的发生,即保证最终一致性。

Cache Aside Pattern
失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。
命中:应用程序从cache中取数据,取到后返回。
更新:先把数据存到数据库中,成功后,再让缓存失效。
最好再搭配上缓存失效,以防止极端情况的出现。

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

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

所以,这也就是Quora上的那个答案里说的,要么通过2PC或是Paxos协议保证一致性,要么就是拼命的降低并发时脏数据的概率,而Facebook使用了这个降低概率的玩法,因为2PC太慢,而Paxos太复杂。当然,最好还是为缓存设置上过期时间

你可能感兴趣的:(redis缓存与数据库的一致性问题)