缓存穿透
缓存穿透,是指在很短的时间内,大量的请求,去查询Redis服务器都查不到,也就是缓存没有命中,于是向数据持久层发起查询,发现也没有,本次查询失败。大量请求直接访问mysql服务器这样会导致缓存直接穿透,MySQL宕机。
解决方案
-
1.布隆过滤器
布隆过滤器是一个中数据结构,对所有可能查询的参数,以hash形式存储,在控制层先进行校验,不符合则丢弃,从而避免对底层存储系统的查询压力。
对于布隆过滤器,是加在Redis和mysql服务器之间的,将mysql中的数据提前存到布隆过滤器中。
布隆算法:
- 2.当存储层不命中后,即使返回的空对象也将其缓存,同时这是一个过期的时间,之后再访问这个资源就会在缓存中获取,保护了后端数据源。这种方式会存在一些问题:
- 如果null能被缓存起来,就需要更多的空间来存更多的键(其他的数据也可能会有null值,不法分子使用id=UUID来进行攻击)
- 即使对空值设置了过期时间,还是会存在缓存层和存储层会有一段时间的窗口不一致,对需要保持一致性的业务有影响。
缓存击穿
很短的时间内,大量的请求,集中访问同一个点,当这个key失效的瞬间,持续的大并发就穿破缓存直接打在mysql服务器上。一般是热点数据。
解决方案
-
设置热点数据永不过期
从缓存层面看,没有设置过期时间,所以不会存在key过期后的问题
-
加互斥锁
分布式锁:使用分布式锁,保证对于每个key,同时只有一个线程去查询后端服务,其他线程没有获取分布式锁的权限,只需要等待。
缓存雪崩
在某一个时间段,缓存集中过期失效,Redis宕机。
如果是key集中过期,到不是非常致命的,比较致命的缓存雪崩,是缓存服务器直接宕机或断网。
解决方案
-
限流降级
在缓存失效后,通过加锁的方式,来控制读写数据库的线程数量,比如对于某一个key,只允许一个线程查询数据和写缓存,其他线程等待。
也可以将一些不必要的服务停掉,来保证核心服务的正常运转。
-
数据预热
在正式部署之前,先把可能的的数据预先访问一遍,手动触发加载缓存。不同的key,设置的过期时间不痛,尽量让key的过期时间均匀。
-
如果是Redis宕机,解决方案是做Redis集群,主从。