redis 缓存穿透、击穿、雪崩

redis 缓存穿透、击穿、雪崩
最新回答
眼眸熏染离情丶

2026-06-24 14:44:42

Redis 缓存穿透、击穿、雪崩详解Redis 缓存穿透

定义:缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中时被动写的,并且出于容错考虑,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到存储层去查询,失去了缓存的意义。在流量大时,可能DB就挂掉了,要是有人利用不存在的key频繁攻击我们的应用,这就是漏洞。

解决方案:

  • 查询不到的写null key:当一个不存在的数据被频繁访问时,可以在缓存中存储一个空值(例如设置为null),并设置一个较短的过期时间。这样,后续对这个数据的访问会直接返回缓存中的空值,而不会再去查询数据库。但需要注意的是,这种方法可能会引入额外的存储空间消耗,并且需要合理设置过期时间以避免长时间占用缓存资源。
  • 设置布隆过滤器:布隆过滤器是一种空间效率很高的随机数据结构,它利用多个哈希函数将元素映射到位数组中,以支持快速的集合成员资格测试。通过引入布隆过滤器,可以在查询缓存之前先判断数据是否存在于布隆过滤器中,从而避免对不存在的数据进行缓存穿透攻击。但需要注意的是,布隆过滤器存在一定的误判率,即可能会将不存在的数据误判为存在。
Redis 缓存击穿

定义:缓存击穿是指一个热点key(通常是高并发访问的热点数据)在缓存中突然失效,此时大量的并发请求会绕过缓存直接访问数据库,导致数据库压力骤增,甚至可能引发数据库崩溃。这种情况通常发生在热点数据被缓存且设置了过期时间的情况下,当该数据在缓存中过期时,如果此时有大量并发请求访问该数据,就会引发缓存击穿。

解决方案:

  • 设置热点数据永不过期:对于某些热点数据,可以将其设置为永不过期,以避免因过期而导致的缓存击穿。但需要注意的是,这种方法可能会导致缓存资源的浪费,因为即使这些数据不再被频繁访问,它们仍然会占用缓存空间。
  • 互斥锁(mutex lock):在访问数据库之前,使用互斥锁来确保只有一个线程或进程能够访问数据库并更新缓存。其他线程或进程在获取锁之前会等待,直到锁被释放。这种方法可以有效地防止缓存击穿,但可能会增加系统的延迟和复杂度。
Redis 缓存雪崩

定义:缓存雪崩是指由于大量缓存数据在同一时间过期,导致大量的并发请求直接访问数据库,从而引发数据库崩溃的现象。这种情况通常发生在缓存数据设置了相同的过期时间,并且这些过期时间恰好集中在同一时间段内。

解决方案:

  • 过期时间随机:为了避免大量缓存数据在同一时间过期,可以将它们的过期时间设置为随机值。这样,即使存在多个缓存数据需要同时过期,它们的过期时间也会分散在不同的时间段内,从而避免缓存雪崩的发生。
  • 设置热点数据永不过期:与缓存击穿类似,对于某些热点数据,可以将其设置为永不过期,以避免因过期而导致的缓存雪崩。但同样需要注意缓存资源的浪费问题。
  • 构建多级缓存:通过构建多级缓存(例如内存缓存、磁盘缓存等),可以在不同层级上缓存数据,以减少对底层数据库的访问压力。即使某一层级的缓存发生雪崩,其他层级的缓存仍然可以提供数据支持。
  • 监控与预警:建立完善的缓存监控和预警机制,及时发现并处理缓存异常情况。例如,可以监控缓存的命中率、过期时间分布等指标,当发现异常时及时采取措施进行干预。

综上所述,Redis 缓存穿透、击穿和雪崩是常见的缓存问题,但通过合理的解决方案和策略,可以有效地避免这些问题的发生,确保系统的稳定性和性能。