菜鸟笔记
提升您的技术认知

redis缓存三兄弟

redis缓存三兄弟

在 Redis 缓存体系中,“缓存三兄弟” 通常指的是缓存穿透缓存击穿缓存雪崩,这三个是缓存场景中常见的典型问题,会严重影响系统性能甚至导致服务崩溃。以下是对它们的详细解析:

1、缓存穿透
问题描述
  • 场景:客户端请求不存在于缓存和数据库中的数据,导致请求直接穿透缓存层,每次都访问数据库。
  • 危害:大量无效请求会压垮数据库,甚至引发DDoS 攻击
成因
  • 恶意攻击:攻击者故意请求不存在的键(如随机字符串)。
  • 业务逻辑漏洞:如用户输入非法参数,查询不存在的数据。
解决方案
  1. 布隆过滤器(Bloom Filter)

    • 原理:在请求进入数据库前,用布隆过滤器快速判断数据是否存在。若不存在,直接拒绝请求,避免穿透到数据库。
    • 适用场景:数据基数大、更新频率低的场景(布隆过滤器更新成本较高)。
  2. 空值缓存

    • 原理:当查询结果为 null 时,仍将空值存入缓存(设置较短过期时间,如 5 分钟),避免相同请求反复查询数据库。
    • 注意:需设置合理过期时间,防止缓存大量无效数据。
  3. 参数校验

    • 对请求参数进行合法性校验(如 ID 格式、范围限制),提前拦截无效请求。
2、缓存击穿
问题描述
  • 场景热点数据的缓存过期瞬间,大量请求同时访问数据库,导致数据库压力激增。
  • 关键词单个热点键、缓存过期、并发请求
成因
  • 热点数据(如秒杀商品、热门新闻)的缓存设置了固定过期时间,到期时大量用户请求同时到达。
解决方案
  1. 热点数据永不过期

    • 不设置过期时间,通过其他机制(如异步线程)主动更新缓存(需注意数据一致性)。
  2. 加互斥锁(Mutex)

    • 原理:当缓存失效时,仅允许单个请求访问数据库并重建缓存,其他请求等待锁释放后从缓存获取数据。
    • 实现方式
      • 使用 Redis 的 SET NX 命令实现分布式锁(如 set lock_key unique_value nx px 10000)。
      • 注意设置锁的过期时间,避免死锁
  3. 提前更新缓存

    • 在缓存过期前(如剩余 10% 时间),异步提前刷新缓存,避免到期时被动重建。
3、缓存雪崩
问题描述
  • 场景大量缓存键同时过期Redis 服务宕机,导致大量请求直接涌入数据库,造成数据库负载过高甚至崩溃。
  • 关键词大量键过期、缓存不可用、请求激增
成因
  • 批量缓存设置了相同或相近的过期时间,到期时集体失效。
  • Redis 集群故障(如主从切换、节点宕机),导致缓存服务整体不可用。
解决方案
  1. 分散过期时间

    • 在设置缓存过期时间时,添加随机时间偏移(如 TTL = 3600 + random(600)),避免大量键同时过期。
  2. 提升缓存高可用性

    • 采用 Redis 集群(Cluster)或主从复制(Master-Slave)架构,结合 Sentinel 实现自动故障转移,减少单点故障影响。
  3. 熔断降级

    • 通过熔断器(如 Hystrix、Resilience4j)监控数据库负载,当压力超过阈值时,直接返回预设的默认值或提示信息,保护数据库。
  4. 限流

    • 通过限流组件(如 Guava RateLimiter、Redis 限流)限制单位时间内的请求量,避免突发流量压垮系统。
  5. 二级缓存

    • 使用本地缓存(如 Caffeine、Ehcache)作为一级缓存,Redis 作为二级缓存,降低对 Redis 的依赖。
4. 三兄弟对比总结
问题 核心原因 典型场景 解决方案核心思路
缓存穿透 请求不存在的数据 恶意攻击、非法参数查询 过滤无效请求、缓存空值
缓存击穿 单个热点键过期,并发请求 热点商品秒杀、突发流量 避免并发重建、延长热点键存活
缓存雪崩 大量键过期或缓存服务不可用 批量缓存到期、Redis 宕机 分散过期时间、增强系统容错