雪崩

简单讲:就是 Redis 挂了或者大量的键失效(击穿是一个热点 key 失效),请求都打到数据库了,所以数据库叫一下就死了

Redis服务器挂了,所有流量全部打到数据库,数据库肯定挂了,如果这个时候,重启数据库,那么数据库只能又被新流量给打死

缓存雪崩的事前事中事后的解决方案如下。

  • 事前:redis 高可用,主从+哨兵,redis cluster,避免全盘崩溃。

  • 事中:本地 ehcache 缓存 + hystrix 限流&降级,避免 MySQL 被打死。

  • 事后:redis 持久化,一旦重启,自动从磁盘上加载数据,快速恢复缓存数据。

限流,限制每秒只能有多少个请求通过,其余的全部降级,返回默认值,友情提示重试,或者空白值

限流可以保证数据库不会挂,数据库不挂,那么对用户来说,至少有一部分用户的请求是可以被处理的,系统不挂,对用户来说,就是多刷新几次就可能刷新出来一次

击穿

缓存击穿,就是说某个 key 非常热点,访问非常频繁,处于集中式高并发访问的情况,当这个 key 在失效的瞬间,大量的请求就击穿了缓存,直接请求数据库,就像是在一道屏障上凿开了一个洞。

解决方式也很简单,可以将热点数据设置为永远不过期;或者基于 redis or zookeeper 实现互斥锁,等待第一个请求构建完缓存之后,再释放锁,进而其它请求才能通过该 key 访问数据。

穿透

key 对应的数据在数据源并不存在,每次针对此 key 的请求从缓存获取不到,请求都会到数据源,从而可能压垮数据源。比如用一个不存在的用户id获取用户信息,缓存数据库 都没有,若黑客利用此漏洞进行攻击可能压垮数据库。

解决方案一:将击透的 key 也缓存起来,但是时间不能太长,缺点就是无法过滤动态的 key,每次进来都是不同的 kye 那其实作用就很有限了

解决方案二:使用布隆过滤器: 热点数据等场景(具体看使用场景)

布隆过滤器是什么?

布隆过滤器可以理解为一个不怎么精确的 set 结构,当你使用它的 contains 方法判断某个对象是否存在时,它可能会误判。但是布隆过滤器也不是特别不精确,只要参数设置的合理,它的精确度可以控制的相对足够精确,只会有小小的误判概率。

当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在