赞
踩
Redis和MySQL的默认的更新策略是旁路缓存策略,旁路缓存策略又有写策略和读策略
写策略:更新时,先更新数据库,再更新缓存
读策略:读取数据时,如果命中缓存,就直接返回;如果未命中缓存,就查询数据库,并构建缓存,再将数据返回
更新数据时,按照默认策略,首先会更新数据库,再删除缓存
但是并发情况下,有其他线程再读取到该数据的旧值,而恰好该数据是第一次访问,未构建缓存,就上面的删除缓存后重新构建了,导致缓存中的仍然是旧值,数据库里的是新值。
如此导致数据库中的数据和缓存中的不一致。详情流程可见下图
方案1:Redis给key设置较短的过期时间,即使数据不一致,数据很快也会过期。缺点就是会影响缓存命中率
方案2:采用延时双删策略。
(1)先淘汰缓存
(2)再更新数据库
(3)休眠相应的时间后,再次清除缓存
它的原理就是:写请求先删缓存,如果这时有读请求就会构建一个旧缓存,第(3)步休息相应的时间,就是为了保证旧缓存构建成立,写请求然后醒来就把旧缓存给清除掉,下次读操作就会直接到数据库中读取新值了。
它缺点也很明显,这个休眠时间不是很好把握,所以该策略不是很推荐使用。
方案3:先更新数据库,再删除缓存,配合消息队列,异步重试
为了有一个兜底方案,避免删除缓存失败,需要进行失败重试,使用MQ消息队列来完成异步重试,同步重试会影响吞吐量,所以通常会采用异步重试的方案
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。