-
缓存击穿
-
问题描述
-
设置的过期时间到了,然后热点key过期了
-
大量的请求同时查询一个key时此时这个key(热点key)正好失效,就会导致大量的请求都打到数据库上面去
-
-
-
解决方案
-
加互斥锁。在并发的多个请求中,只有第一个请求线程能拿到锁并执行数据库查询操作,其他的线程拿不到锁就阻塞等着,等到第一个线程将数据写入缓存后,后面的线程进来发现已经有缓存了,就直接走缓存
-
热点数据不过期,直接将缓存设置为不过期,然后由定时任务去异步加载数据,更新缓存
-
-
-
缓存穿透
-
问题描述
-
请求去查询一条记录,先查redis无,后查mysql无,都查询不到该条记录,但是请求每次都会打到数据库上面去,导致后台数据库压力暴增这种现象我们称为缓存穿透
-
-
解决方案
-
缓存空值并设置一定时间的过期时间
-
相同key(增强回写)
-
第一次来查询redis和mysql都没有,返回null给调用者,但是增强回写后第二次来查,此时redis就有值了,因为增强回写机制,增强回写机制会在redis中存储在redis和mysql都没有查到的key,然后value设置为一个自定义的值,当我们看到返回自定义值时说明发生了缓存穿透
-
-
不同key(必须要设置过期时间)
-
增强回写机制只能解决key相同的情况,当key不同时,会导致redis写入大量和业务无关的数据,这时需要设置key的过期时间
-
-
-
采用布隆过滤器,在访问redis和mysql之前先通过布隆过滤器过滤一下,把不存在的key直接返回,从而减少对DB的查询压力
-
有不一定有没有一定没有,因为存在查询的数据的时候通过3次哈希后映射到的位置可能和不相同数据映射到的位置相同,这就导致误判,本来不存在判断为存在
-
-
-
-
缓存雪崩
-
问题描述
-
Redis设置缓存时采用了大量相同的过期时间key,导致缓存在某一时刻大量的key同时失效,请求全部转发到DB,DB瞬时压力过重挂掉
-
-
解决方案
-
设置二级缓存,二级缓存指的是除了 Redis 本身的缓存,再设置一层缓存,本地缓存,当 Redis 失效之后,先去查询二级缓存,而不是直接去查数据库
-
服务降级,Redis出现问题,不去数据库查询,而是直接返回默认值给用户---404
-
在原有的失效时间基础上增加一个随机值,使得过期时间分散一些
-
-
为什么不允许布隆过滤器修改或者删除元素?
-
因为通过三次哈希函数的计算映射后,不同的数据可能映射到同一个位置,这样就导致如果我们删除其中的一个元素,将对应位置的1改为0,可能导致其他并不想删除的元素和想要删除的元素被一块删除