Redis 如何有效防止缓存穿透、击穿和雪崩问题?

新手上路,请多包涵

Redis怎么解决缓存穿透、击穿、雪崩

想看看大佬是怎么解决的

阅读 1.8k
4 个回答

点击这里查看解决办法。

  1. 查询不存在的数据做空对象缓存
  2. null 的key需要检查,如果是就直接返回
  3. 特别大的流量系统,通常会做二级缓存,本地缓存不存在再去查询redis
新手上路,请多包涵

这个问题的本质还是大量请求直接访问到了数据库;可以从提高缓存的命中率,时效性等方面着手。

缓存穿透、缓存击穿和缓存雪崩的解决方案:

缓存穿透

问题描述:缓存和数据库中都没有的数据被频繁请求,导致每次请求都要访问数据库,增加数据库负载。
例子: 假设有一个用户请求一个不存在的商品ID(如ID为9999的商品),每次请求都会直接查询数据库。
解决方案

  1. 布隆过滤器

    • 在请求到达缓存之前,先通过布隆过滤器检查ID是否存在。如果布隆过滤器判断ID 9999不存在,则直接返回空结果,避免查询数据库。
    • 优点:占用空间小,判断效率高。
    • 缺点:存在误判的可能,但可以通过增加哈希函数和布隆过滤器的大小降低误判率。
  2. 缓存空对象

    • 如果查询ID 9999的商品结果为空,将这个空结果缓存一段时间(如5分钟),下次请求ID 9999时直接返回缓存的空结果。
    • 优点:简单易实现,能有效减少数据库访问压力。
    • 缺点:需要合理设置空结果的过期时间,以避免长期缓存无效数据。

缓存击穿

问题描述:缓存中没有但数据库中有的数据被频繁请求,通常是因为缓存过期,导致大量请求同时访问数据库。
例子: 某个热门商品(如ID为1001的商品)缓存突然失效,导致大量用户同时请求该商品,直接访问数据库。
解决方案

  1. 互斥锁

    • 当缓存失效时,第一个请求获取互斥锁,其他请求等待。第一个请求从数据库获取数据并更新缓存后,释放锁,其他请求再从缓存获取数据。
    • 优点:能有效防止缓存击穿。
    • 缺点:会增加系统开销,可能影响性能。
  2. 逻辑过期

    • 设置商品ID 1001的缓存逻辑过期时间为10分钟,实际过期时间为15分钟。在逻辑过期时间内,返回旧数据并异步更新缓存。
    • 优点:用户可以持续访问旧数据,避免缓存击穿问题。
    • 缺点:实现较为复杂,需处理异步更新的可靠性问题。

缓存雪崩

问题描述:大量缓存同时失效,导致大量请求直接访问数据库,可能导致数据库崩溃。
例子: 假设在某个时间点,大量商品缓存同时失效(如午夜时分所有商品缓存都设置为24小时过期),导致大量请求直接访问数据库。
解决方案

  1. 设置不同的过期时间

    • 为每个商品缓存设置不同的过期时间(如商品ID 1001的缓存过期时间为23小时,ID 1002的为25小时),避免同时失效。
    • 优点:简单有效,能分散缓存过期时间。
    • 缺点:需合理设置过期时间的范围。
  2. 多级缓存

    • 在本地缓存和分布式缓存之间设置多级缓存,用户请求先访问本地缓存,再访问分布式缓存,最后才访问数据库。
    • 优点:提高系统的容错性和可用性。
    • 缺点:需要额外管理本地缓存与分布式缓存的一致性。
  3. 限流和降级

    • 在高并发情况下,限制请求速率,并在必要时返回默认数据或提示用户稍后再试。
    • 优点:能有效减少对数据库的瞬时压力,保证系统稳定。
    • 缺点:需要合理的限流策略和降级方案。
推荐问题
宣传栏