入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

分布式缓存--序列4--缓存更新策略/缓存穿透/缓存雪崩

创建时间:2016-11-28 投稿人: 浏览次数:3496

前面几篇关于缓存的文章主要介绍了相关原理,本篇从业务应用角度讲述相关的使用策略。

被动更新

设置key过期的时间,让其自动失效。

主动更新

更新DB的时候,同时更新缓存。一般业务都是主动更新和被动更新结合使用。

先更新DB,后更新缓存

对于主动更新来说,存在一个问题:你是先更新缓存,后更新DB;还是反过来?
下面分别分析以下2个场景,假设有2个线程,t1, t2:
(1) 先更新缓存,后更新DB。假设有如下的执行系列:

t1更新缓存;
t2读缓存,因为t1把缓存更新了,导致t2没读到。从db中读,然后更新缓存;
t1更新DB。

上述操作系列会导致缓存脏数据。

(2)先更新DB,后更新缓存。假设有如下操作序列:

t1更新DB;
t2更新DB;
t2更新缓存;
t1更新缓存。

上述操作系列同样会导致缓存脏数据。

一句话,无论谁先谁后,只要更新缓存和更新DB不是原子的,就可能导致不一致。只是从实际业务来讲,一般缓存也都是保持“最终一致性“,而不是和DB的强一致性。

并且一般建议先更新DB,再更新缓存,优先保证DB数据正确。

但如果一定要“强一致性“,就不能用上面的解决方案了。有一个解决办法就是不要更新缓存,而是直接删除缓存(让缓存过期),但这会增加缓存的miss率。

缓存更新的实现策略

策略1:业务方(调用者)更新

传统上,更新缓存都是由业务方来做,也就是由调用者负责更新DB和缓存。

策略2:DB中间件监听DB变化,更新缓存

现在有种新的办法就是利用DB中间件监听DB变化(比如阿里的Canal中间件,点评的Puma),从而对缓存进行更新。
这种办法的一个好处就是:把缓存的更新逻辑,和业务逻辑解藕。业务只更新DB,缓存的更新被放在另外一个专门的系统里面。

所谓“缓存穿透“,就是指某个key,先查cache没查到,再查db也没有查到。

这种key的存在,会导致cache一直没办法命中,压力一直打在db上面。如果访问很高频,可能会压垮DB。

解决办法其实也很简单:当查询DB没查到时,往缓存中写入一个空值(缺省值),这样第2次再查,就不会打到DB上了。

所谓“缓存雪崩“,是指缓存的机器挂了,所有请求直接打到DB上面,从而导致DB也挂掉。

这种问题的解决策略,一般有以下2个方面:
(1)提高缓存的HA。比如缓存的主从复制。
(2)对DB的访问实行限流、降级。

关于限流、降级的做法,参见分布式序列的另外一篇文章“服务熔断、降级、限流、异步RPC – HyStrix“。

声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。