首先,数据库与缓存双写不可能做到强一致性,只能做到最终一致性。如果项目要求是强一致性的,那么不能使用缓存。
从理论上来说,给缓存设置过期时间,是保证最终一致性的解决方案。这种方案下,我们可以对存入缓存的数据设置过期时间,所有的写操作以数据库为准,对缓存操作只是尽最大努力即可。也就是说如果数据库写成功,缓存更新失败,那么只要到达过期时间,则后面的读请求自然会从数据库中读取新值然后回填缓存。因此,接下来讨论的思路不依赖于给缓存设置过期时间这个方案。
方案一:先更新缓存,再更新数据库
这种方式肯定不行的,缓存更新成功,数据库更新失败,怎么办?
方案二:先更新数据库,再更新缓存
有一致性问题。如果线程A先更新了数据库,然后线程B更新了数据库,接下来线程B更新了缓存,最后线程A更新了缓存。按道理线程A更新缓存应该比线程B更新缓存早才对,但是因为网络等原因,B却比A更早更新了缓存,这就导致了脏数据,因此不考虑。
方案三:先删缓存,再更新数据库
也会导致不一致。比如请求A进行写操作,删除了缓存,请求B查询发现缓存不存在,去数据库查询得到旧值并将旧值写入缓存,最后请求A将新值写入数据库。上述情况就会导致不一致的情形出现。而且,如果不采用给缓存设置过期时间策略,该数据永远都是脏数据。
方案四:先更新数据库,再删除缓存
老外提出了一个缓存更新套路,名为《Cache-Aside pattern》。其中就指出:
失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。
命中:应用程序从cache中取数据,取到后返回。
更新:先把数据存到数据库中,成功后,再让缓存失效。
知名社交网站facebook也在论文《Scaling Memcache at Facebook》中提出,他们用的也是先更新数据库,再删缓存的策略。
来源:CSDN
作者:wuychn
链接:https://blog.csdn.net/qmqm011/article/details/104563876