面试的时候如果简历上面写了了解Redis,那面试官百分之99.99会问你有没有了解过redis的雪崩、击穿、穿透
那到底是什么情况下会出现这几个现象呢,接下来一个一个举例子
雪崩
Redis的雪崩可以这么来理解
举个例子,我零点有个秒杀活动大量用户涌入,假设当时每秒 6000 个请求,本来缓存在可以扛住每秒 5000 个请求,但是缓存当时所有的Key都失效了。此时 1 秒 6000 个请求全部落数据库,数据库必然扛不住,它会报一下警,真实情况可能DBA都没反应过来就直接挂了。此时,如果没用什么特别的方案来处理这个故障,DBA 很着急,重启数据库,但是数据库立马又被新的流量给打死了。这就是我理解的缓存雪崩。
因为key大面积的实效的话,那一瞬间有redis和没有效果是一样的,那个数量级的数据请求直接全部访问数据库,对数据库来说就是灾难级的,假如这些数据将一个用户服务搞崩了,那依赖用户的其他服务的接口就全部崩了,如果没有做熔断降级一些的操作的话,那基本上一个项目就是全崩了,然后你去重启,等你重启成功的时候,用户早就去睡觉了,最后用户体验极差,什么垃圾产品。
总的来说,雪崩就是在某一瞬间,大面积的key都失效了,同时有大量的请求去直接请求数据库,导致数据库直接瘫痪,从而导致服务直接崩了
解决办法:
有两个解决办法
1.就是在设置过期时间的时候,在后面随机加一个时间,这样不会导致同一秒内大面积的key失效
setRedis(Key,value,time + Math.random() * 10000);
2.就是给key设置永不过期,然后在数据更新的时候同步进行更新
穿透
穿透是在数据库和redis中都查询不到数据,就比如说,数据库的id都是大于0的,但是我用小于0的参数一直去访问,每次都绕过了redis直接访问数据库,但是数据库里面也查询不到数据,如果一直请求攻击,并发量再高点的话,数据库就直接崩了
解决办法:
1.我会在接口层增加校验,比如用户鉴权校验,参数做校验,不合法的参数直接代码Return,比如:id 做基础校验,id <=0的直接拦截等
2.从缓存取不到的数据,在数据库中也没有取到,这时也可以将对应Key的Value对写为null、位置错误、稍后重试这样的值具体取啥问产品,或者看具体的场景,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。
3.还有我记得
Redis
还有一个高级用法布隆过滤器(Bloom Filter)
这个也能很好的防止缓存穿透的发生,他的原理也很简单就是利用高效的数据结构和算法快速判断出你这个Key是否在数据库中存在,不存在你return就好了,存在你就去查了DB刷新KV再return
击穿
这个和雪崩相似但是又不是完全一样,雪崩是大面积的缓存失效,直接给DB打崩了,像是一整个地面都塌陷了,而击穿是某一个点特别热门,这个key一直都是特别高并发的存在,当这个key突然失效的时候,一瞬间很多访问量访问这一个点,请求都落在数据库上面了,就类似于一个地面被凿穿了一个洞,导致数据库崩了
击穿简单来说就是,在某一秒一个热门的key失效了,同事刚好又有很多请求去请求这个key,并发量高了之后,数据库扛不住就崩了
解决办法:
设置热点数据永远不过期。或者加上互斥锁就能搞定了