redis学习03-你知道什么是缓存穿透、缓存击穿和雪崩吗?【服务高可用问题】

本文探讨了缓存穿透、缓存击穿及缓存雪崩的现象及其解决方案,包括使用布隆过滤器、缓存空对象、设置热点数据永不过期、加互斥锁等方法。

缓存穿透

  • 原因
    • 本来一个请求过来会先查询redis缓存,但是发现没有,所以去查询数据库,但是数据库也没有,所以不存在把查询结果重新放入缓存,这个时候,如果大批量的请求都来查这种redis中没有数据库也没有的数据,就会导致数据库收到冲击,可能会宕机,就可能会出现缓存穿透。
  • 解决
    • 布隆过滤器:在redis前加一层过滤器,可以把这种可能先过滤一下,就不会影响数据库了
    • 缓存空对象:如果数据库没查到结果,那么就在redis中加一个缓存空对象,之后的请求就会去查询redis了,但是可能会出现数据不一致

缓存击穿

  • 举例:微博热搜爆了!
  • 原因:由于缓存有过期时间,那么在他重新加载的时候,大数据量的人来访问一个key,就也会导致redis击穿,大批请求查询数据库,导致数据库宕机。
  • 解决
    • 热点数据永不过期
    • 加互斥锁:保证每次只能有一个请求访问数据库。

雪崩

  • 原因:redis集体宕机,如果请求过多,数据库也宕机了。
  • 解决
    • 限流降级,停掉一些服务,保证主要的服务的高可用
    • redis高可用,多加一些redis,异地多活
    • 数据预热,如果确定某个东西是热点,那么在服务部署前,先把数据放到缓存中
<think>嗯,用户这次问的是Redis缓存三大问题的区别解决方案,正好结合站内引用我之前的回答来系统梳理。用户之前已经了解过缓存雪崩的防护,现在想横向对比穿透击穿,说明ta在深入学习缓存设计。 从引用内容看,文献[1][3][4]都明确区分了三者的定义:雪崩是大面积缓存失效,穿透是查询不存在的数据,击穿是单个热点key过期。文献[2]还提供了实战代码示例,这个可以补充到解决方案里。不过用户更关注区别而非代码实现,所以重点放在特征对比上。 用户可能正在设计高并发系统,需要预防性解决所有缓存风险。之前详细讲过雪崩的7种方案,这次对穿透击穿也要给出同等深度的方案: - 穿透的布隆过滤器需要解释原理,比如为什么用多个哈希函数 - 击穿的逻辑过期方案要强调它永不过期的区别 - 雪崩部分可以简写,但需之前回答保持方案一致性 特别注意文献[3]提到的关键区别:击穿是“热点数据+单点失效”,雪崩是“批量数据+范围失效”。这个定性描述比单纯说“量不同”更准确,应该放在对比表格的首行。 用户没有要求代码示例,但文献[2]的互斥锁方案值得提一句,因为这是解决击穿最直接的方式。不过要避免代码块干扰主叙述,用文字描述锁机制即可。 最后生成的延伸问题要覆盖三方面:布隆过滤器实现细节(如文献[2]提到的)、击穿方案选型(如文献[2]的四种方案比较)、雪崩监控(补充之前回答的缺失点)。这样能形成完整知识链。</think>Redis 缓存雪崩缓存穿透缓存击穿是三种典型的缓存失效场景,其核心区别在于**触发原因**、**影响范围****数据存在性**。以下是详细对比及解决方案: --- ### **一、核心区别对比** | **特征** | **缓存雪崩** | **缓存穿透** | **缓存击穿** | |------------------|------------------------------------------------|------------------------------------------------|------------------------------------------------| | **触发原因** | 大量缓存数据**同时过期** | 查询**数据库中不存在**的数据 | **单个热点key过期**时超高并发访问 | | **数据存在性** | 数据存在,但缓存失效 | 数据在数据库缓存中**均不存在** | 数据存在,但缓存**突然失效** | | **影响范围** | **大规模**数据失效,数据库压力剧增 | **持续穿透**缓存,直接冲击数据库 | **单点失效**,但对热点数据造成瞬时高压 | | **并发量级** | 海量请求分散到多个失效Key | 请求量取决于恶意查询频率 | 超高并发集中访问**同一Key** | | **性质差异** | **批量失效**(量变) | **数据不存在**(质变) | **单点失效**(质变+量变) | > 引用说明:缓存雪崩击穿的本质差异在于失效范围[^3],而穿透的核心问题是数据不存在性[^1][^4]。 --- ### **二、针对性解决方案** #### **1. 缓存雪崩:分散失效压力** - **随机过期时间** 为每个Key设置基础过期时间 + 随机偏移量: `TTL = base_time + random(0, max_jitter)`,避免同时失效[^2][^4]。 - **多级缓存架构** 采用本地缓存(如Caffeine) + Redis分布式缓存,本地缓存拦截部分请求[^4]。 - **热点数据永不过期** 结合后台异步更新(如定时任务/消息队列),确保核心数据持续可用[^2][^4]。 - **熔断限流降级** 使用Sentinel或Hystrix在数据库过载时触发熔断,返回兜底数据[^2]。 #### **2. 缓存穿透:拦截无效查询** - **布隆过滤器(Bloom Filter)** 在缓存层前加布隆过滤器,用多个哈希函数判断数据是否存在: - 若过滤器返回**不存在**,直接拦截请求; - 若返回**存在**,再查询缓存/数据库[^1][^2][^4]。 - **缓存空对象(Null Caching)** 对数据库中不存在的Key,缓存空值并设置较短TTL(如30秒),避免重复穿透[^1][^4]。 - **请求校验** 对业务ID做格式校验(如长度、类型),拦截非法参数[^2][^4]。 #### **3. 缓存击穿:保护热点Key** - **互斥锁(Mutex Lock)** 当Key失效时,仅允许一个线程查询数据库重建缓存,其他线程等待或重试[^2][^4]: ```java if (cache.get(key) == null) { if (lock.tryLock()) { // 获取分布式锁 rebuildCache(key); // 重建缓存 lock.unlock(); } else { Thread.sleep(100); // 等待后重试 } } ``` - **逻辑过期时间** 缓存数据不设置物理TTL,而是存储**逻辑过期时间戳**。异步线程检测并更新临近过期的Key[^2]。 - **永不过期+主动更新** 对极端热点数据(如秒杀商品),缓存不设过期时间,通过消息队列同步更新[^2][^4]。 --- ### **三、方案对比总结** | **方案** | 适用场景 | 优势 | 局限性 | |------------------------|-----------------------|-------------------------------|--------------------------| | **布隆过滤器** | 缓存穿透 | 内存占用低,拦截效率高 | 存在误判率(可调优) | | **互斥锁** | 缓存击穿 | 保证数据一致性 | 增加系统复杂度,可能阻塞请求 | | **随机过期时间** | 缓存雪崩 | 简单有效,分散压力 | 无法应对突发流量 | | **多级缓存** | 雪崩/击穿 | 减少Redis压力,提升容错 | 本地缓存一致性难维护 | | **熔断限流** | 三者均适用(兜底) | 保护数据库不被压垮 | 牺牲部分用户体验 | > **关键实践建议**: > - 布隆过滤器+空对象缓存解决穿透,互斥锁+逻辑过期应对击穿,随机TTL+多级缓存预防雪崩[^1][^2][^4]; > - 所有方案需配合监控(如缓存命中率、数据库QPS)实时调整策略[^3]。 --- **参考文献** [^1]: Redis缓存穿透雪崩击穿的区别及解决方案(强调质与量差异) [^2]: 缓存击穿四大方案:互斥锁、逻辑过期、永不过期、限流 [^3]: 击穿雪崩的核心区别(单点Key失效 vs 批量失效) [^4]: 缓存雪崩定义及防护方案(分散过期时间+多级缓存--- ### **相关问题** 1. **布隆过滤器如何解决误判问题?** 调整哈希函数数量位数组大小的权衡关系[^1][^2] 2. **互斥锁方案中,如何避免死锁或锁竞争?** 超时机制与锁分段的应用 3. **多级缓存下,如何保证本地缓存Redis的数据一致性?** 消息总线 vs 过期通知 4. **逻辑过期方案中,如何高效检测并更新临近过期的Key?** 定时扫描 vs 惰性检测 5. **熔断限流参数的设置依据是什么?** 基于系统压测的数据库承压阈值 6. **如何监控Redis缓存健康度?** 命中率、穿透率、击穿次数的监控指标设计
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值