什么是缓存雪崩、缓存穿透、缓存击穿以及解决方案
什么是缓存雪崩?
场景:
例如淘宝平台,某位后端研发童鞋小明,将Redis缓存中所有key(假设有1000w的key)的过期时间设置为同一时间,假设都设置为5秒;5秒后,所有key都过期了,这时候就需要从数据库中拿到key对应的数据,重新设置到缓冲中,这是正常流程。其实,当有1000w的请求打到数据库中,试问哪家的数据库可以抗住这个压力(除非特别有????),肯定是顶不住的,最后数据库宕机,凉了~,绩效也没了。
图解:
解决方案:
-
要保证redis的高可用,可以使用主从+哨兵或redis cluster,避免服务器不可用;
-
使用本地ehcache缓存+hystrix限流/降级,当redis查询不到结果,可以从本地缓存中查询,如果还是查不到,就要从数据库中查询,不过这里要有一层限流,防止数据库被打死;
-
使用redis的持久化RDB+AOF组合策略,防止缓存丢失并且可以快速恢复数据;
-
需要给redis缓存中的key值设置过期时间时,尽量不要设置同一时间,如果业务场景允许可以将缓存时间加个随机数。
什么是缓存穿透?
场景:
还是拿淘宝平台举例,某黑客发现淘宝有羊毛可以褥,就不断地重试某个接口,并且随机生成一串字符串传过去,由于开发接口时,阿里童鞋小明可能会这么写,当在缓存中查询不到数据,就从数据库查询,判断是否存在;
那么,问题就来了,黑客在写脚本的时候,不小心多按了几个0,每次请求10w次,这10w次请求都是会打到数据库,要是频繁被这样请求,数据库不宕机才怪;
图解:
解决方案:
-
对请求参数做校验,例如可以用正则;
-
可以改一下逻辑,当查询不到数据后,可以直接返回空,不要再从数据库查询了;
-
可以引入布隆过滤器,过滤一些异常的请求。
什么是缓存击穿?
场景:
以淘宝为例,在淘宝平台上,肯定存在很多热点商品即热点数据,当热点数据过期后,会并发的从数据库中查到数据后,重新设置缓存;试想淘宝双十一,剁手党有人在抢东西,并发量非常大,数据库也是顶不住这么大的并发量的,顶不住就凉了。
图解:
解决方案:
-
可以将热点数据的过期时间设置为永久有效(有人可能会问,万一这个热点商品下架了,这个缓存不就成了了脏数据吗?其实会有这种场景存在,主要还是具体情况具体分析,看业务场景吧);
-
维护一个定时任务,将快要过期的key重新设置;
-
可以使用分布式锁,当在缓存中拿不到数据时,使用分布式锁去数据库中拿到数据后,重新设置到缓存;
欢迎关注我的微信公众号,里面有很多干货,各种面试题