edis雪崩和穿透击穿的解决方法(edis雪崩和穿透)
导语:Redis异常之雪崩、击穿、穿透
Redis异常之雪崩、击穿、穿透Redis在生产中较为容易遇到的三大问题,也是面试中问的比较多的问题便是Redis的缓存雪崩、缓存击穿、缓存穿透,这三大问题也是Redis缓存中比较典型的问题,下面分点详细聊聊。
缓存雪崩缓存过期时间集中Redis雪崩其实大多数人都知道其中的一个原因便是缓存集中过期,一般都是设置过期时间的时候统一将一批数据设置相同的过期时间,在某个点集中过期,导致大批量的请求打到缓存后面的数据库,导致数据库压力巨大,无法及时处理大批量的请求。
解决办法解决办法一是大家熟知的处理方式也是相对简单的,就是在设置过期时间的时候将原有过期时间加上一个几分钟内的随机值,保证键值不会集中过期即可。
除了设置随机过期时间外还可以通过服务降级的方式,当系统发现大量请求在redis上无法命中,大量请求堆积在数据库上,这时系统可以将部分系统非核心业务服务降级返回预定的错误信息,核心业务还是可以通过数据库查询得到请求结果,尽量减少数据库的请求压力。
那么除了缓存集中过期还有什么场景呢?
缓存实例宕机当Redis缓存实例无法提供缓存服务时,相当于绕开了缓存直接请求数据库了,这时也会导致缓存雪崩。
解决办法解决办法一就是服务熔断,当请求访问缓存出现大面积失败,将触发服务熔断,返回预定义的错误信息,过一段时间后放行少部分的请求访问缓存,如果请求全部成功那么将撤销熔断,如果请求还是失败,过一段时间再次重试即可。
解决办法二就是服务限流,当发生缓存雪崩时限制请求的最大个数,保证后台数据库的正常处理。
对于这种一般都是单机故障,单机宕机的概率较高,我们的解决办法一般是事前预防,我们可以构建高可用的集群主从架构,这样即使有主节点宕机还能选举从节点为主节点继续提供服务。
不论是服务降级、服务熔断、服务限流其实都是有损方案,会对系统其它模块造成影响,应尽量避免。
缓存击穿缓存击穿一般出现场景就是热点数据过期,热点数据突然过期那么大量请求将打在数据库上,而数据库无法处理大的并发请求有可能导致后台数据库服务宕机,这个解决办法也是很简单,不给热点数据过期时间,这样热点数据永不过期,自然不会造成缓存击穿这种异常场景。
缓存穿透缓存穿透指要访问的数据既不在缓存中也不在数据库中,这样也就导致了缓存中没有数据去数据库中查询,但是数据库中也不存在该数据,就不会写到缓存中,这样一来缓存就成了摆设,如果大量请求这种不存在的数据,对缓存Redis和数据库来讲都是压力巨大的。
恶意攻击出现缓存穿透的最常见场景其实就是恶意攻击,攻击者可以生成大量这种数据库中不可能存在的数据,请求我们的服务器。造成服务异常。
解决办法既然是不正常的数据那么需要前端加入参数校验,将页面的不合理数据请求拦截。当数据库中数据不存在我们可以缓存空值或缺省值,这样避免缓存穿透。采用布隆过滤器,快速判断数据是否存在,虽然布隆过滤器有可能存在误判的情况,但如果布隆过滤器发现数据不存在那么一定不存在,如果布隆过滤器发现数据存在,那么该数据不一定存在,这并不影响解决缓存穿透问题,这仅仅只有少部分的请求会走到数据库,所以布隆过滤器是最优方案。浅聊布隆过滤器布隆过滤器底层就是由一个全是0的bit数组和N个哈希函数构成,当我们在布隆过滤器中标记某个值存在时,一般分为如下步骤
使用N个哈希函数,分别计算其哈希值。将N个哈希值对bit数组的长度取模,得到存放的数组下标。将得到的数组下标的值置为1。上图存在3个哈希函数,也就是每次需要标记三个位置的值才能确定一个值是否存在,当我们需要依靠布隆过滤器确定值是否存在时我们只需要确定多个哈希值对应的数组下标是否全部为1,只要有一个为0那么值肯定不在数据库中。
布隆过滤器为什么会存在一定的误判率呢?其主要原因还是因为哈希冲突,数组长度有限那么不同的值可能会映射到相同的位置上,所以降低误判的方法一般是增加哈希函数或者扩大bit数组的长度,这样做确实能降低误判率,但也带来一个问题那就是哈希函数的增加将影响计算性能,扩大内存会更加占用空间,所以我们在使用布隆过滤器时需要在性能、内存、误判率上面做取舍。
总结Redis的异常情况我们更多的是以预防为主,预防能解决大部分问题
缓存雪崩,设置合理的过期时间,避免键值集中过期。缓存击穿,热点键值不要设置过期时间。缓存穿透,前端需要做合法性校验,后端可以采用布隆过滤器快速检验。本文内容由小媛整理编辑!