数据库和缓存双写的一致性问题

本秂侑毒 提交于 2020-02-29 17:30:31

首先,数据库与缓存双写不可能做到强一致性,只能做到最终一致性。如果项目要求是强一致性的,那么不能使用缓存。

从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。这种方案下,我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。因此,接下来讨论的思路不依赖于给缓存设置过期时间这个方案。

方案一:先更新缓存,再更新数据库

这种方式肯定不行的,缓存更新成功,数据库更新失败,怎么办?

方案二:先更新数据库,再更新缓存

有一致性问题。如果线程A先更新了数据库,然后线程B更新了数据库,接下来线程B更新了缓存,最后线程A更新了缓存。按道理线程A更新缓存应该比线程B更新缓存早才对,但是因为网络等原因,B却比A更早更新了缓存,这就导致了脏数据,因此不考虑。

方案三:先删缓存,再更新数据库

也会导致不一致。比如请求A进行写操作,删除了缓存,请求B查询发现缓存不存在,去数据库查询得到旧值并将旧值写入缓存,最后请求A将新值写入数据库。上述情况就会导致不一致的情形出现。而且,如果不采用给缓存设置过期时间策略,该数据永远都是脏数据。

方案四:先更新数据库,再删除缓存

老外提出了一个缓存更新套路,名为《Cache-Aside pattern》。其中就指出:

失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。

命中:应用程序从cache中取数据,取到后返回。

更新:先把数据存到数据库中,成功后,再让缓存失效。

知名社交网站facebook也在论文《Scaling Memcache at Facebook》中提出,他们用的也是先更新数据库,再删缓存的策略。

详细内容参考这篇文章:https://www.cnblogs.com/rjzheng/p/9041659.html

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!