缓存穿透、缓存雪崩、缓存击穿、缓存热点分析及解决方案
大纲
1.缓存正常使用流程
2.缓存穿透
3.缓存击穿
4.缓存雪崩
5.缓存热点
1.缓存的使用
一般缓存的正常使用流程是,先根据key从缓存中获取,如果缓存中存在数据则返回,不存在则到数据库中获取,获取到则更新到缓存,并将数据返回,没有获取到则抛出异常或返回空值;
2.缓存穿透
指缓存和数据库都没有的数据。
场景:被黑客攻击,故意访问大量不存在的数据,此时有可能将系统搞崩。
解决方案1:增加key值校验,直接过滤不满足条件的key;
解决方案2:如果查询存储系统即数据库也没有找到数据,则直接设置一个默认值(空值或具体值)并存到缓存中,此时将缓存过期时间设置的短点,比如30s;
解决方案3:及时识别爬虫,做好监控和处理
3.缓存击穿
指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,数据库压力瞬间增大。
场景:一个key非常热点,在大并发几种访问的情况下,缓存失效,持续的大并发就会穿破缓存,直达数据库,导致数据库连接异常
解决方案1:互斥锁,缓存失效的时候,先去获取锁,获取到锁的可以去请求数据库,没有得到锁的失眠一段时间重试(可递归重试)
解决方案2:异步更新策略,无论key是否取到值都返回,如果缓存失效,异步起一个线程去更新缓存(项目启动时需要进行缓存预热)
解决方案3:设置热点数据永不过期
4.缓存雪崩
指缓存集中过期失效或缓存服务器宕机或断网,和缓存击穿不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。
其中缓存集中过期倒不是非常致命,因为能集中过期,基本上也是同一时间创建的缓存,能抵住创建的压力,自然也可以抵住更新的压力,致命的是缓存服务器宕机或断网。
场景:高并发秒杀系统由于旧缓存已经失效,所有的缓存都去访问存储系统重新生成缓存,对存储系统造成巨大的性能压力,可能会造成系统崩溃。
解决方案一:更新锁,对缓存更新操作加锁保护,保证只有一个线程能够进行缓存更新,未能获取更新锁的线程要么等待锁释放后重新读取缓存,要么返回默认值(空值或具体值)。对于集群系统则需要使用到分布式锁,如zookeeper。
解决方案二:定时读取后台更新,定时去读取缓存,发现没有则更新换缓存;
解决方案三:消息队列通知后台更新,业务线程一旦发现缓存失效就通过消息队列通知后台线程更新
解决方案四:双缓存,缓存A设置失效时间,缓存B不设置失效时间,自己做缓存预热。先从缓存A读取数据,有则返回,没有则从缓存B读数据,有则直接返回,异步启动一个更新线程同时更新缓存A和缓存B。
电商项目解决方案:
1.不同分类商品,设置不同的缓存周期;
2.同一分类商品,加一随机因子分散过期时间;
3.热门类目缓存时间长一些,冷门的短一些;
5.缓存热点
大部分甚至所有业务请求都命中同一份缓存数据。
场景:粉丝庞大的明细发一条微博,可能会引起大量的粉丝来围观。
解决方案:复制多份缓存,将请求分散到多台缓存服务器上
缓存穿透递归重试图: