首页 > 数据库 >Redis的缓存穿透、击穿、雪崩及解决方案

Redis的缓存穿透、击穿、雪崩及解决方案

时间:2024-06-09 19:33:51浏览次数:13  
标签:缓存 过期 数据库 Redis 雪崩 数据 节点

Redis的缓存穿透、击穿、雪崩是三个不同的缓存机制问题,在设计和使用Redis缓存系统时,我们需要考虑以下三种常见的问题:缓存穿透、缓存击穿和缓存雪崩。

缓存穿透(Cache Penetration)

定义:

缓存穿透:缓存穿透是指查询一个在缓存和数据库中都不存在的数据,用户不断发起这样的请求,由于缓存不会缓存这样的查询结果,每次请求都会去数据库查询,可能会导致数据库压力过大。缓存穿透是指客户端请求的数据在缓存中和数据库中都不存在,这样缓存永远不会生效,这些请求都会直接打到数据库。

影响:

  • 数据库压力增大,性能下降。
  • 可能导致系统崩溃。

解决方案:

  1. key校验+缓存空对象:
    首先在接口层面判断key是否有效(如id<=0或者校验key的长度等),这样会在接口层面拦掉一部分不合规则的请求。如果校验通过后,去查询数据库,当发现数据在数据库中不存在时,也将其存入Redis中,但value为空。
    • 优点:实现简单,维护方便。
    • 缺点:额外的内存消耗,可能造成短期的不一致。
  2. 布隆过滤器:
    使用布隆过滤器判断请求的数据是否可能存在于Redis中。
    • 优点:内存占用较少,没有多余key。
    • 缺点:实现复杂,存在误判可能。

缓存击穿

定义:

缓存击穿是指缓存中某个热点数据失效,此时有大量并发请求同时访问这个失效的数据,导致这些请求直接访问数据库,造成数据库压力过大,甚至导致数据库崩溃。

影响:

数据库承受高并发压力,可能导致崩溃。

解决方案:

  1. 锁机制:
    使用锁机制或分布式锁机制,避免大量并发请求同时访问失效的热点数据。例如:如果未命中缓存,先获取互斥锁,获取锁之后要再次检查缓存,如果还是未命中进行缓存重建,这样当其他线程来的时候就会获取锁失败,这时我们让这个线程休眠一会,重新查询缓存,如果命中就返回,如果没命中再次尝试获取锁,假设这次获取锁成功了,还是再次检查缓存,如果未命中重建缓存。
    优点:

    • 可以有效防止多个请求同时访问数据库。
    • 实现简单,可以利用Redis的分布式锁或其他锁机制。

    缺点:

    • 可能增加系统的响应时间,因为请求需要等待锁释放。
    • 如果锁的粒度太粗,可能会导致性能瓶颈。
  2. 逻辑过期:
    不设置TTL,而是设置逻辑上过期标识,需要过期时直接删除标识。
    优点:

    • 数据持久性:不设置TTL意味着数据将永久存储在Redis中,直到被显式删除或Redis实例被关闭。这对于需要长期存储的数据来说是有益的,因为它确保了数据的持久性。
    • 减少过期检查的开销:Redis需要定期检查键的TTL以确定哪些键已经过期,并从缓存中删除它们。对于不设置TTL的键,Redis不需要执行这个过期检查,从而减少了CPU的开销。

    缺点:

    • 内存消耗:不设置TTL可能导致Redis内存中的数据持续增长,最终耗尽所有可用内存。这可能需要定期手动清理不再需要的数据,或者监控Redis的内存使用情况并采取适当的措施。
    • 数据陈旧:没有TTL的缓存数据可能会变得陈旧或过时,因为它们永远不会自动过期。这可能需要额外的逻辑来定期更新或刷新缓存数据。
    • 无法利用LRU等缓存淘汰策略:Redis提供了多种缓存淘汰策略(如LRU、LFU等),用于在内存不足时自动删除一些缓存项。不设置TTL的缓存项将不会被这些策略考虑,因为它们永远不会过期。

缓存雪崩(Cache Avalanche)

定义:

缓存雪崩是指大量的缓存数据在同一时间过期,或者Redis故障宕机,导致大量的请求都直接访问数据库,可能会导致数据库压力过大,甚至导致整个系统崩溃。

影响:

数据库承受巨大压力,可能导致崩溃。

解决方案:

  1. 多级缓存:
    采用多级缓存架构,减少缓存层的压力。
    优点:

    • 可以提高系统的缓存命中率,减少对数据库的访问。
    • 可以通过不同级别的缓存来分担访问压力。

    缺点:

    • 实现复杂,需要维护多个缓存系统。
    • 可能需要额外的逻辑来处理不同缓存系统之间的数据同步和一致性。
  2. 随机过期时间:
    为每一个缓存数据设置不同的过期时间,并保持一定的随机性。
    优点:

    • 可以有效避免大量缓存同时失效的情况。
    • 实现简单,只需在设置缓存时加入随机时间即可。

    缺点:

    • 可能导致缓存的过期时间不够准确。
    • 在某些场景下可能仍然会出现缓存雪崩的情况。
  3. 限流、熔断:
    在缓存层和数据库层之间添加限流、熔断等措施,避免因突发流量导致系统崩溃。
    优点:

    • 可以有效保护系统免受突发流量的冲击。
    • 可以实现系统的自动恢复和降级处理。

    缺点:

    • 可能会牺牲部分用户请求的处理。
    • 需要合理设置限流和熔断的阈值,避免误判或过度保护。
  4. Redis高可用:
    使用主从复制和哨兵机制,确保Redis的高可用性。

    • 主从复制
      优点:

      • 数据冗余和高可用性:主从复制通过将数据复制到多个从节点上,实现了数据的冗余备份。当主节点发生故障时,可以快速切换到从节点,确保服务的连续性。
      • 读写分离:主节点处理写操作,而从节点处理读操作,提高了系统的读写性能,尤其适用于读多写少的场景。
      • 扩展性:可以通过增加从节点来扩展系统的读取能力,提高整体性能。

      缺点:

      • 单点故障:虽然主从复制提供了数据冗余,但仍然存在单点故障的风险。如果主节点发生故障,需要手动进行主从切换操作,可能导致服务中断。
      • 主节点压力:在写操作频繁的场景下,主节点的压力可能会比较大,因为它需要同时处理写请求和将数据同步到从节点。
      • 数据一致性:虽然Redis的主从复制是异步的,但在极端情况下(如网络延迟、主节点宕机等),可能会导致主从数据不一致。
    • 哨兵机制
      优点:

      • 自动故障转移:哨兵机制可以监控Redis主从节点的状态,当主节点发生故障时,可以自动选择一个从节点进行故障转移,确保服务的连续性。
      • 简化管理:通过哨兵机制,可以简化Redis集群的管理和维护工作,减少人工干预。
      • 高可用性:结合主从复制和哨兵机制,可以构建高可用的Redis集群,确保服务的稳定性和可靠性。

      缺点:

      • 配置和管理复杂:哨兵机制需要配置多个哨兵节点,并设置复杂的监控和故障转移策略。这增加了配置的复杂性和管理的难度。
      • 单点故障:虽然哨兵机制可以自动进行故障转移,但如果所有的哨兵节点都发生故障,那么整个Redis集群将无法正常工作。
      • 无法实现数据分片:哨兵机制主要关注于Redis主从节点的故障转移和监控,而不支持数据分片。如果需要实现数据分片,需要采用Redis Cluster等其他方案。

总结:
Redis的缓存穿透、击穿、雪崩是缓存机制中常见的问题,它们都可能对系统性能和可用性产生严重影响。通过合理的缓存策略、数据结构设计以及系统架构优化,可以有效地避免这些问题,提高系统的稳定性和性能。

标签:缓存,过期,数据库,Redis,雪崩,数据,节点
From: https://blog.csdn.net/Kris_zwl/article/details/139563419

相关文章

  • Redis-0-目录
    0.背景本文,参考B站博主轩辕的编程宇宙-趣话Redis系列进行整理由于最近复习了Redis相关内容,自己整理了笔记,所以刚好结合博主聊到的内容串一下。字幕,借助:GreasyFork中的BilibiliCC字幕工具整理内容段落整合,由GPT完成。1.内容1.1Redis缓存管理机制你好,我是REDIS。一个叫An......
  • Redis-11-Redis与Mysql的数据一致性
    1.是什么数据一致性呢,讲的就是缓存中的数据和db中的数据是否能一致。2.为什么先看我这篇文章,了解下缓存策略:Redis-6-三种缓存读写策略在文章中,介绍了并发场景下的一致性问题,我们已经确定了一个基本思路:先更新db,再删除缓存。这个方案,奠定了我们在读写操作时的基本思路。2.1......
  • 互联网大厂的缓存策略:抵抗超高并发的秘密武器
    大家好,我是冰河~~最近,有小伙伴私信我:冰哥,我最近出去面试,面试官问我如何设计缓存能让系统在百万级别流量下仍能平稳运行,我当时没回答上来。接着,面试官问我之前的项目是怎么使用缓存的,我说只是缓存了一些数据。当时确实想不到缓存还有哪些用处,估计这次面试是挂了。冰哥,你可以给我讲......
  • 如何使用互斥锁解决缓存击穿(热点Key)
    还是基于上一篇的代码。当热点缓存失效时,会出现大量请求直接打到数据库,可能会导致数据库压力过大,甚至崩溃。为了解决这一问题,我们可以使用互斥锁(Mutex)来控制缓存重建过程。改造代码如下:publicShopqueryWithMutex(Longid){Stringkey=CACHE_SHOP_KEY+id;//......
  • redis做为缓存,mysql的数据如何与redis进行同步呢?
    让我们一步步来实现如何让MySQL数据库的数据和Redis缓存保持同步。想象一下,MySQL是一个大仓库,存放着所有重要的货物(数据),而Redis则像是一个快速取货窗口,让你能更快拿到常用的东西。为了让两者保持一致,我们需要搭建一座桥梁,让仓库里的变动能及时反映到取货窗口。第一步:理解同步......
  • Redis-6-三种缓存读写策略
    2.1旁路缓存CacheAsidePattern(旁路缓存)适合读请求比较多的场景CacheAsidePattern中服务端需要同时维系db和cache,并且是以db的结果为准。2.1.1写先更新db直接删除缓存2.1.2读先读缓存有,则从缓存返回。没有,从db中读取返回。再将读取的数据写入缓存......
  • Redis集群和高可用性:保障Redis服务的稳定性
    I.引言A.对Redis的简单介绍和其在现代Web应用中的角色 Redis(REmoteDIctionaryServer)是一个开源的、基于内存的键值数据库,它支持多种数据结构,如字符串、哈希、列表、集合、有序集合等。由于Redis的高性能和丰富的数据类型,使其在现代Web应用中广泛使用。例如,它可以用......
  • bin下的bpl 与 redist下的bpl 区别
    由于我们是host+bpl开发,需要在delphi的安装目录寻找,我们需要的带的包,搜索发现很多包有2份,bin目录下有一份,redist目录下还有一份,通过下图可以看到这2份的大小是一致的,那么他们是一模一样的吗;我把他们复制出来,用在线MD5来看他们的MD5,发现这2份是一样的!......
  • redis命令实践 详细教程
    Redis是一个高性能的键值对数据库,支持多种数据结构,如字符串、哈希、列表、集合、有序集合等。以下是一份详细的Redis命令实践教程,包括常用命令和示例。1.连接Redis服务器使用redis-cli工具连接到Redis服务器:redis-cli-h<hostname>-p<port>-a<password>-h:指定Redis......
  • redis常用命令详细带例子
    Redis是一个功能丰富的键值对数据库,支持多种数据结构和操作。以下是一些常用Redis命令的示例,以及如何在实践中使用它们。基本操作PingRedis服务器PING例子:检查Redis服务器是否响应。redis-cliPING设置键值对SETkeyvalue例子:将字符串"World"与键"greeting"关联。re......