再谈缓存雪崩、穿透、击穿

一、雪崩

​ 缓存雪崩在面试redis中经常会被问到,通常的回答会是缓存雪崩是因为大面积的缓存失效,打崩了DB。但这么说有点笼统,可以再详细的举例说说

1. 原因:

那么缓存雪崩的原因都可能有哪些?

  1. redis实例宕机

    redis实例宕机这点很好理解,就是redis挂了,本来会先访问redis获取数据,redis挂掉以后,无法从redis获取到数据了,流量都打到数据库上了,数据库承受不住如此大的流量,于是数据库也挂了。

  2. 大量数据同时失效

    大量数据同时失效,这点可能是属于人祸,一般情况想让大量数据同时失效也很难的,除非比如被人调用了flushall命令,这种情况我还真的见过,在原来公司的测试环境,就真的会有人连接公用的redis,然后调用flushall命令清除测试数据,结果把别人的测试数据也一块清除掉了。另外一种情况,是公司封装的redis工具包,自动设置key的超时时间为当天的12:00,到12点所有的key一块过期,够刺激吧,虽然这可能是业务需要,但是这种操作真的台危险了。

2. 解决

解决方案分为一下几个阶段:

  • 事前:

    • redis高可用,redis实例部署要有主从,非集群的实例,可以部署sentinel自动故障时切换主从,集群类型的实例天然是高可用的,在此基础上所有的集群的主实例都添加从实例就可以了。另外还有一些其他的部署规范,如:主从实例不能部署到同一台机器上等等。

    • 均摊分配redis key的失效时间,只要不要集中在一点就好,以几分钟的随机数让缓存错峰失效

  • 事中:应用程序集成限流和降级的功能,在redis崩溃或者数据大量失效的情况下降低访问或返回默认结果,避免DB被流量被打死。

  • 事后:使用redis持久化数据快速恢复缓存数据。RDB和AOF两种方式各有优势和缺点,AOF丢失的数据会是少一些。

二、穿透

1. 原因:

​ 缓存穿透原因相应的比较简单,就是获取不存在的数据。正常情况下,接口从缓存中获取数据,如果获取不到,会从数据库中查询数据并设置到缓存中。但是这个数据如果在数据库中没有,那每次的获取就会一直从数据库中查询,缓存没有起到作用。流量大的话全部打到数据库上,就把数据库给打死了。

2. 解决:

​ 这种情况一般的解决方案是在从数据库中获取不到值时,就在缓存中给对应的key设置一个自定义的值,比如我们公司是设置一个自定义的EmptyObject对象,下次获取值时,如果发现是EmptyObject对象的话,就返回null值,如果不是就查库,但是要注意一点,设置EmptyObject对象的Key应该设置一个较短有效期,这样,既可以防止频繁查询数据库造成穿透,又可以防止后续数据库中可以获取到值但从缓存中获取仍是null值的情况。

​ 但这种空对象缓存的情况,只针对相同id的请求有效,如果是黑客的恶意攻击,大量的每次id不同的请求,仍然会造成大量的请求到数据库,而且生成大量的EmptyObject对象的话,redis服务器也会产生大量的脏数据。这种情况还可以在缓存查询的位置增加一个guava(单机)或redis(分布式)的布隆过滤器判断是否存在该key,如果不存在则直接返回,相当于redis缓存外又加了一层保护,及时因为hash冲突导致过了布隆过滤器,能到缓存及数据库的数据仍是少数。

​ 另外应该从接口方面限制参数规则验证,如果参数不符合规则直接抛异常,常见的如对外提供的接口,参数应该是大于0的,如果传入小于等于0的参数,则直接返回错误。

三、击穿

缓存击穿是指一个Key非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个Key在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库。

缓存击穿的解决方案一个是使用数据库的二级缓存,使用ehcache实现二级缓存高并发的流量不会都打到数据库上,另外就是使用限流工具,限制访问数据库的接口的流量。

也可以使用差异化有效期双缓存机制进行解决,即,热点key 同时设置两个缓存 A 、B,两个的失效时间不同,B的失效时间比A的失效时间长,在缓存A失效导致无法查询出数据的时候,就从缓存B查,在更新缓存时,先更新缓存B,后更新缓存A。这样可以解决击穿问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值