一.缓存雪崩

缓存雪崩:大量应用请求无法在Redis缓存中进行处理,应用请求频繁访问数据库,导致数据库压力激增。

产生原因:

缓存中有大量数据同时过期,导致大量请求无法得到处理

  • 数据保存在缓存中,并设置了过期时间时,如果某一时刻,大量数据同时过期,此时,应用程序再访问这些数据的话,就会发生缓存缺失。
  • 应用就会把请求发送给数据库,从数据库中读取数据。
  • 如果应用的并发请求量很大,那么数据库的压力也就很大,这回进一步影响到数据库的其他业务请求处理,进而导致数据库崩溃。

大量数据同时失效带来的缓存雪崩问题,两种解决方案:

  • 我们可以避免给大量数据设置相同的过期时间。 如果业务曾的确要求有数据同时失效,你可以用 EXPIRE命令给每个数据设置过期时间时,给这些数据的过期时间,给这些数据过期时间增加一些较小的随机数 不同数据的过期时间有差别,但是差别又不大,避免大量数据同时过期。 同时保证数据基本在相近时间失效,仍能满足业务需求。
  • 除了微调过期时间,我们通过服务降级来应对缓存雪崩。

服务降级:是指发生缓存雪崩,针对不同的数据采用不同的处理方式:

  • 当业务应用访问的是非核数据时候,暂时停止从缓存中查询这些数据,而是直接返回预定义信息或者空数据。
  • 当业务应用访问的是核心数据,仍然允许查询缓存,如果缓存缺失也可以继续通过数据库读取。

产生雪崩的两种情况:

  • 大量数据同时失效
  • Redis实例故障宕机

一个Redis实例可以支持数万级别的请求处理吞吐量,而单个数据库只能支持数千级别的请求处理吞吐量,他们两个的处理能力可能相差了近乎十倍。一旦缓存雪崩,Redis缓存失效,那么数据库直接承受十倍请求压力,导致崩溃。

二.Redis实例发生宕机产生缓存雪崩

1. 业务系统中实现服务熔断或者请求限流机制

服务熔断:发生缓存雪崩时,为了防止发生连锁的数据库雪崩,甚至整个系统崩溃,我们暂停业务应用对缓存系统的接口访问。

具体实现:业务调用缓存接口时,缓存客户端不再请求Redis,而是直接返回,等到Redis缓存实例重新恢复服务以后,在允许应用请求发送到缓存系统。

优点:避免了大量请求因缓存缺失,而积压到数据库系统,保证了数据库系统的正常运行。

2.事先预防

  • 主从节点构建Redis缓存高可用集群
  • 当Redis缓存的主节点故障宕机了,从节点切换为主节点,继续提供缓存服务避免缓存实例宕机造成的缓存雪崩问题。

三.缓存击穿

缓存击穿:针对某个访问非常频繁的热点数据请求,无法在缓存中进行处理,紧接着访问该数据的大量请求,一下子都发送到后端数据库,导致数据库压力激增影响数据库处理其他请求。

缓存击穿发生在热点数据过期失效时。

解决方案:

  • 对于访问特别频繁的热点数据,我们不再设置过期时间。
  • 对于热点数据的请求访问,都可以在缓存中进行处理。

四.缓存穿透

  • 缓存穿透:要访问的数据既不是Redis缓存中也不再数据库中,导致请求在访问缓存时,发生缓存缺失,再去访问数据库时,发现数据库中也没有要访问的数据。
  • 如果应用持续有大量请求访问数据,就会同时给缓存和数据库带来巨大压力

产生缓存穿透的原因:

  • 业务层误操作:缓存中的数据和数据库中的数据都被误删除,所以缓存和数据库中都没有数据;
  • 恶意攻击:专门访问数据库中没有的数据

三种解决方案:

1.缓存空值或者缺省值

  • 一旦发生缓存穿透,针对查询数据在Redis缓存一个空值或者业务层协商确定的缺省值。应用发生后续请求在进行查询时,可以直接从Redis读取空值或者缺省值返回给业务应用,避免大量请求发送给数据库处理,保持数据库的正常运行。

2.使用布隆过滤器快速判断数据是否存在,避免从数据库中查询数据是否存在,减轻数据库压力。

3.前端对非法请求校验,避免请求进入缓存或者数据库。

五.总结

问题原因应对方案
缓存雪崩

大量数据同时过期

缓存实例宕机

给缓存数据的过期时间加上小的随机数避免同时过期

缓存降级熔断

请求限流

Redis缓存主从集群

缓存击穿热点数据过期热点数据不设过期时间
缓存穿透数据在缓存和数据库中不存在

缓存空值

布隆过滤器

请求入口校验