自学内容网 自学内容网

Redis生产问题(缓存穿透、击穿、雪崩)——针对实习面试

Redis生产问题

在这里插入图片描述

什么是缓存穿透?

缓存穿透是指当请求查询数据库中不存在的数据时,由于在缓存中也没有该数据,导致每次请求都要到数据库查询,这可能会对数据库造成巨大压力,甚至导致数据库崩溃。

这种情况通常发生在以下场景:

  1. 恶意攻击:攻击者故意请求数据库中不存在的数据,导致数据库压力增大。
  2. 数据误删除:当数据库中的数据被删除后,缓存中相应的数据没有被删除,导致后续请求无法命中缓存,直接访问数据库。
  3. 数据更新:当数据库中的数据更新后,缓存中的数据没有及时更新,导致后续请求无法命中缓存,直接访问数据库。

如何解决缓存穿透?

在面试中,当被问到如何解决缓存穿透问题时,你可以从以下几个方面来回答:

  1. 缓存空对象
  • 策略:当数据库中不存在请求的数据时,将空结果缓存起来,并设置一个较短的过期时间。这样,下次相同的请求就会直接命中缓存,避免了对数据库的查询。

  • 实现:在代码中,你可以检查查询结果是否为null,如果是,则将null值缓存,并设置一个较短的TTL(Time To Live)。

  1. 布隆过滤器
  • 策略:使用布隆过滤器来预先判断请求的数据是否可能存在于数据库中。如果布隆过滤器判断数据不存在,则直接返回,不查询数据库。

  • 实现:布隆过滤器是一种空间效率很高的概率型数据结构,它可以告诉你一个元素是否可能存在于集合中。如果布隆过滤器说元素不存在,那么这个元素一定不存在;如果它说元素存在,那么这个元素可能存在也可能不存在。

  1. 限制请求
  • 策略:对于某些特定的请求,比如请求频率过高的用户或IP,可以限制其访问频率,防止恶意攻击。

  • 实现:可以使用限流算法(如令牌桶或漏桶算法)来限制请求频率,或者使用防火墙规则来限制特定IP的请求。

  1. 数据校验
  • 策略:在查询数据库之前,对请求的数据进行校验,确保请求的数据是合法的,避免请求不存在的数据。

  • 实现:在应用层添加逻辑来校验请求参数,确保它们符合预期的格式和范围。

什么是缓存击穿?

缓存击穿是指在缓存中某个热点数据在过期或被删除后,突然失效,导致大量请求同时到达数据库,这种我们称为缓存击穿。

缓存击穿的原因是一个备受欢迎的缓存数据突然失效或宕机,导致重建缓存时,由于是热点Key,所以有不断的线程来查和重建缓存,导致大量数据请求直接到达数据库。

如何解决缓存击穿?

在解决缓存击穿问题时,可以采用以下几种策略:

  1. 设置热点数据永不过期
    对于一些极端热点数据,可以将其缓存设置为永不过期,或者设置一个非常长的过期时间。这样可以避免因为缓存过期导致的缓存击穿问题。(不建议使用

  2. 使用互斥锁
    当缓存失效时,使用互斥锁来保证只有一个线程去查询数据库并更新缓存,其他线程等待。例如在Java中,可以使用ReentrantLock来实现互斥锁。

  3. 提前缓存预热
    在系统上线前,提前将热点数据加载到缓存中,避免大量请求同时触发缓存未命中的情况。(建议使用

  4. 布隆过滤器
    使用布隆过滤器预先判断请求的数据是否可能存在于数据库中。如果布隆过滤器判断数据不存在,则直接返回,不查询数据库。

缓存穿透和缓存击穿有什么区别?

缓存穿透和缓存击穿是缓存系统中两种不同的问题,它们的主要区别在于:

  1. 缓存穿透

    • 原因:请求查询的数据在数据库中不存在,导致缓存中也没有该数据。
    • 影响:大量请求直接打到数据库,增加数据库压力。
    • 解决方法:缓存空对象、使用布隆过滤器、数据校验等。
  2. 缓存击穿

    • 原因:缓存中某个热点数据在过期或被删除后,突然失效
    • 影响:大量请求同时到达数据库,可能导致数据库压力过大。
    • 解决方法:设置热点数据永不过期、使用互斥锁、逻辑过期等。

简而言之,缓存穿透是因为请求的数据根本不存在,而缓存击穿是因为请求的数据在缓存中突然失效
两者都可能导致数据库压力增大,但原因和解决策略有所不同。

什么是缓存雪崩?

缓存雪崩是指在Redis缓存中,大量的Key在同一时间过期,导致大量的请求同时到达数据库,造成数据库压力过大甚至宕机的情况。

缓存雪崩通常发生在以下场景:

  1. 大量Key同时过期:在Redis中设置了大量的Key,并且这些Key的过期时间相同或接近,当这些Key同时过期时,会导致大量的请求同时到达数据库。

  2. 缓存服务宕机Redis服务突然宕机,导致缓存服务不可用,所有的请求都会直接打到数据库上。

  3. 缓存数据全为热点数据:如果缓存中存储的都是热点数据,当缓存服务出现问题时,所有的请求都会直接打到数据库上。

如何解决缓存雪崩?

  1. 分散过期时间

    • 设置不同的过期时间:对于缓存的数据,设置不同的过期时间,避免大量Key同时过期
    • 使用随机数:在设置过期时间时,给每个Key的过期时间添加一个随机数,使得它们不会同时过期。
  2. 持久化存储

    • 使用Redis的持久化功能(如RDB和AOF),确保在Redis重启后能够从磁盘恢复数据,减少因缓存服务宕机导致的数据库压力。
  3. 高可用缓存集群

    • 部署Redis集群,通过主从复制和分片来提供高可用性和扩展性,确保缓存服务不会因为单个节点的故障而完全不可用。
  4. 限流和降级

    • 限流:使用限流算法(如令牌桶或漏桶)来控制请求的流入速率,避免过多请求同时到达数据库。
    • 降级:在缓存服务不可用时,提供降级服务,如返回一些静态数据或缓存中已有的旧数据,以保证系统的基本可用性。
  5. 备用缓存方案

    • 使用本地缓存或其他缓存服务作为备用缓存方案,当主缓存服务不可用时,可以切换到备用缓存。
  6. 预加载缓存

    • 在系统低峰时段,预加载可能即将过期的缓存数据,确保缓存中的数据始终可用

原文地址:https://blog.csdn.net/weixin_73527957/article/details/143588779

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!