redis缓存策略小结

比较常用的缓存策略,同样这也是facebook的缓存策略: 
1. 读:应用程序从cache中取数据,取到后返回。 
2. 读:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。 
3. 增删改:先把数据存到数据库中,成功后,再让缓存失效。

这里针对第3点,会有一些其他的用法,乍一看都是很正常的,但后来细细一想其实都是有问题的。 
比如(1)“先更新redis,然后更新DB” 
(2)“先更新DB,然后更新缓存” 
(3)“先删除缓存,然后再更新数据库”

让我们来看一看这三个都有什么问题,先假设更新DB和更新redis都是在同一个事务中,其中一个失败了就都不操作,或者假设这两个动作都不会失败。

先看第(1)个和第(2)个,Quora上的这个问答已经说明了原因:https://www.quora.com/Why-does-Facebook-use-delete-to-remove-the-key-value-pair-in-Memcached-instead-of-updating-the-Memcached-during-write-request-to-the-backend。

为了更生动形象说明问题,我画了张图来证明它的不可行性:

从图中可以看出,两个并发写操作,由于某些原因(io阻塞,cpu时间片分配,协程调度,网络原因等等),导致goroutine2的更新DB晚于goroutine1的更新DB,但是redis中此时的数据goroutine1的,而DB中的数据时goroutine2的,这就出现了不一致的问题,DB中是脏数据。

第(2)个是同样的道理,见下图:

下面我们来看第(3),两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,会把老数据读出来后放到缓存中,然后更新操作更新了DB。于是,在缓存中的数据还是老的数据,导致缓存中的数据是脏的,而且还一直这样脏下去了。
--------------------- 
作者:jeffrey11223 
来源:CSDN 
原文:https://blog.csdn.net/jeffrey11223/article/details/78823047 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/zl1zl2zl3/article/details/85757631