Redis生产问题,缓存雪崩,击穿,

78 阅读4分钟

Redis生产问题

缓存穿透

什么是缓存穿透

用户访问的多个key没有保存在缓存中,也不存在于数据库中,用户的访问直接访问到数据库,导致数据库的崩溃

解决方法

  1. 缓存空结果: 当查询条件在数据库中不存在时,可以将空结果(null或特定的空值)缓存一段时间。这样,对于同样的查询,后续的请求可以直接从缓存中获取空结果,避免了对数据库的重复查询。
  2. 请求校验: 在查询前,对请求进行合法性校验,比如检查请求的参数格式、范围或是否存在。对于非法或可疑的请求,直接拒绝或返回错误信息,减少无效查询。
  3. 限流与黑名单: 通过对IP地址或请求频率进行限制,可以防止恶意的高并发请求。同时,可以维护一个黑名单,对于已知的恶意请求源进行屏蔽。
  4. 布隆过滤器(Bloom Filter) : 布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否在一个集合中。通过将所有可能存在的数据哈希到一个足够大的位数组中,可以快速判断一个查询是否可能存在。如果布隆过滤器表明一个元素不存在,那么可以直接返回,无需查询数据库。

缓存击穿

什么是缓存击穿?

用户访问的key不存在缓存中,用户直接去访问数据库,导致数据库的访问量过大导致数据库的宕机,一般是数据库中保存的热点key失效导致的。

解决方法:

  1. 设置热点数据永不过期: 对于那些访问频率非常高、数据更新不频繁的热点数据,可以考虑将其设置为永不过期,或者设置一个非常长的过期时间,以减少缓存失效的可能性。
  2. 限流与熔断: 实施请求限流,限制单位时间内对数据库的请求次数,或者在数据库负载过高时,熔断机制可以暂时停止接收请求,直到数据库压力减轻。
  3. 预热缓存: 在系统启动时,预先加载热点数据到缓存中,避免在系统运行初期由于缓存未准备好而导致的缓存击穿。

缓存击穿和缓存穿透的区别

缓存穿透是key不在缓存中也不在数据库中

缓存击穿是保存在缓存中的key已经失效,数据库中存在,会直接访问数据库

缓存雪崩

什么是缓存雪崩?

缓存在同一时间大面积的失效或缓存系统突然不可用的情况,导致大量的请求都直接落到了数据库上,对数据库造成了巨大的压力。 这就好比雪崩一样,摧枯拉朽之势,数据库的压力可想而知,可能直接就被这么多请求弄宕机了。

解决方法:

  • 分散缓存失效时间:为缓存项设置不同的过期时间,避免大量缓存项同时失效。
  • 使用降级策略:当缓存系统不可用时,启用备份方案或降级策略,如返回默认值、使用旧数据或从数据库读取数据并同时更新缓存。
  • 限流和熔断机制:实施请求限流,防止数据库过载;使用熔断器模式,在检测到数据库压力过大时,暂时拒绝部分请求,待压力缓解后再恢复。

缓存击穿和缓存雪崩的区别

缓存击穿只是单个热点key失效,对于系统的整体影响较小

缓存雪崩是同一时间内大量大key同时失效或者缓存系统崩溃

如何保证缓存和数据库数据的一致性?

  1. Cache Aside Pattern(旁路缓存模式)

    • 读操作:首先尝试从缓存中读取数据,如果缓存中没有(缓存未命中),则从数据库读取并将数据写入缓存。
    • 写操作:直接写入数据库,然后删除相关缓存项(而不是更新缓存),让下次读取时重新从数据库加载数据。
  2. Write Behind Caching(写后置缓存)

    • 在这种模式下,写操作首先更新缓存,然后异步地更新数据库。这可以提高写操作的性能,但需要确保异步更新的可靠性和顺序正确性。
  3. 事件驱动的一致性

    • 使用消息队列或事件总线,当数据库数据发生变化时,发送事件通知缓存系统进行相应的更新或清除。
  4. 延迟双删(Lazy Double Deletion)

    • 在更新数据库后,先标记缓存为过期,但不立即删除。这样可以避免在缓存更新期间的短暂不一致性窗口。