redis的穿透&雪崩

2022-05-13 10:59:42 浏览数 (1)

一 缓存穿透

缓存穿透是指查询一个一定不存在的数据(比如连mysql都没得数据,Redis怎么也查不到啊),由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。

在流量大时,可能数据库就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

解决方案

有很多种方法可以有效地解决缓存穿透问题

  • 接口层增加校验,比如用户鉴权校验,参数做校验,明显不合法的参数直接代码Return,比如:我们id必然大于0,可以在接口层用 id 做基础校验,id <=0的直接拦截等。
  • 最常见的则是采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被 这个布隆过滤器拦截掉,从而避免了对底层存储系统的查询压力。布隆过滤器
  • 还有一个更为简单粗暴的方法,如果一个查询返回的数据为空(不管是数据存在不存在,还是系统故障),我们仍然把这个空结果进行缓存,或者写个固定值比如UNKNOW,但它的过期时间会很短,最长不超过五分钟。

二 缓存雪崩

简介:缓存同一时间大面积的失效(比如我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失效,或者redis突然宕机了,请求全部转发到DB,DB瞬时压力过重雪崩

解决方案

预防措施(雪崩前):

  • key集中过期型: 可以给缓存设置过期时间时加上一个随机值时间,使得每个key的过期时间分布开来,不会集中在同一时刻失效
  • redis单机版宕机型: 对redis做高可用框架比如多master做数据分片,并且每个master做主从结构
  • 通用型解决方案:
    • 做多级缓存(比如本地用caffeine做个几百兆缓存放最热点数据),防止整个redis集群宕机之后请求全都打到DB上。
    • 对于请求到数据库的那一层做限流降级,用hystrix或者Sentinel都可以(这种方式比较柔和安全,用户及时一次点不出来,多点几次错过这波高峰或者下次是高峰中没被限流的请求也就刷出来数据了)

失效中措施

1、在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待

2、做二级缓存,一级缓存未查询到数据,则从二级缓存查询

雪崩后后处理

如果雪崩原因是redis宕机的情况,我们需要利用 redis 持久化机制保存的数据尽快恢复缓存

0 人点赞