一、雪崩
? 缓存雪崩在面试redis中经常会被问到,通常的回答会是缓存雪崩是因为大面积的缓存失效,打崩了DB。但这么说有点笼统,可以再详细的举例说说
1. 原因:
那么缓存雪崩的原因都可能有哪些?
-
redis实例宕机 redis实例宕机这点很好理解,就是redis挂了,本来会先访问redis获取数据,redis挂掉以后,无法从redis获取到数据了,流量都打到数据库上了,数据库承受不住如此大的流量,于是数据库也挂了。 -
大量数据同时失效 大量数据同时失效,这点可能是属于人祸,一般情况想让大量数据同时失效也很难的,除非比如被人调用了flushall 命令,这种情况我还真的见过,在原来公司的测试环境,就真的会有人连接公用的redis,然后调用flushall 命令清除测试数据,结果把别人的测试数据也一块清除掉了。另外一种情况,是公司封装的redis 工具包,自动设置key的超时时间为当天的12:00,到12点所有的key一块过期,够刺激吧,虽然这可能是业务需要,但是这种操作真的台危险了。
2. 解决
解决方案分为一下几个阶段:
二、穿透
1. 原因:
? 缓存穿透原因相应的比较简单,就是获取不存在的数据。正常情况下,接口从缓存中获取数据,如果获取不到,会从数据库中查询数据并设置到缓存中。但是这个数据如果在数据库中没有,那每次的获取就会一直从数据库中查询,缓存没有起到作用。流量大的话全部打到数据库上,就把数据库给打死了。
2. 解决:
? 这种情况一般的解决方案是在从数据库中获取不到值时,就在缓存中给对应的key设置一个自定义的值,比如我们公司是设置一个自定义的EmptyObject对象,下次获取值时,如果发现是EmptyObject对象的话,就返回null 值,如果不是就查库,但是要注意一点,设置EmptyObject对象的Key应该设置一个较短有效期,这样,既可以防止频繁查询数据库造成穿透,又可以防止后续数据库中可以获取到值但从缓存中获取仍是null 值的情况。
? 另外应该从接口方面限制参数规则验证,如果参数不符合规则直接抛异常,常见的如对外提供的接口,参数应该是大于0的,如果传入小于等于0的参数,则直接返回错误。
三、击穿
缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库。
缓存击穿的解决方案一个是使用数据库的二级缓存,使用ehcache实现二级缓存高并发的流量不会都打到数据库上,另外就是使用限流工具,限制访问数据库的接口的流量。
|