当前位置: 首页 > java >正文

理清缓存穿透、缓存击穿、缓存雪崩、缓存不一致的本质与解决方案

在构建高性能系统中,缓存(如Redis) 是不可或缺的关键组件,它大幅减轻了数据库压力、加快了响应速度。然而,在高并发环境下,缓存也可能带来一系列棘手的问题,如:缓存穿透、缓存击穿、缓存雪崩、缓存不一致

这些问题听起来名字相似,容易混淆。今天这篇文章,就带大家系统地理解它们的本质区别、发生场景及最佳实践方案


🧩 一图总览

问题类比本质场景是否打DB解决方案
缓存穿透故意找错门请求的是不存在的key用户请求id=-1✅ 每次布隆过滤器、空值缓存
缓存击穿热门商品钥匙丢了热点缓存突然失效秒杀详情失效瞬间访问量激增✅ 高并发打DB加锁、逻辑过期
缓存雪崩大楼停电大量缓存同时失效设置了相同TTL✅ 大规模打DB过期时间加随机值、限流
缓存不一致仓库和门市不同步缓存与数据库更新顺序错误先更新DB再删缓存,删失败✅ 数据错误先删缓存后更新、消息队列

1️⃣ 缓存穿透(Cache Penetration)

📌 本质

指的是请求的数据在缓存和数据库中都不存在,导致每次都穿透缓存打到数据库。

🎯 场景

  • 用户频繁访问不存在的 userId,如:userId = -1

  • 恶意攻击脚本请求随机字符串ID,绕过缓存打数据库

✅ 解决方案

  • 布隆过滤器:构建合法key集合,提前拦截非法请求

  • 空值缓存:对查询结果为空也做短期缓存,避免重复查询

    if (result == null) {redis.set(key, "null", 60); // 缓存空值1分钟
    }
    

2️⃣ 缓存击穿(Cache Breakdown)

📌 本质

某个热点数据在失效瞬间被高并发请求,造成短时间内大量请求直击数据库。

🎯 场景

  • 秒杀系统中某商品详情缓存5分钟,到期那一刻被数万用户请求。

✅ 解决方案

  • 互斥锁:只有一个线程可以查询DB并刷新缓存,其他等待

  • 逻辑过期:缓存中放入“过期时间”,即使过期,旧数据仍返回,由后台线程异步刷新缓存(常见于百度方案)


3️⃣ 缓存雪崩(Cache Avalanche)

📌 本质

大量缓存在同一时间过期,大量请求并发击穿缓存,压垮数据库。

🎯 场景

  • 代码里为所有缓存设置了固定TTL 30分钟,30分钟后集体过期。

✅ 解决方案

  • 过期时间加随机值,错开失效时间

    int ttl = 1800 + RandomUtils.nextInt(300); // 1800±300秒
    redis.set(key, value, ttl);
    
  • 预热缓存机制:启动时提前加载核心数据

  • 限流与熔断机制:保护后端服务


4️⃣ 缓存不一致(Cache Inconsistency)

📌 本质

缓存和数据库中的数据不一致,通常由于更新顺序或更新失败导致。

🎯 场景

  • 先更新数据库,再删除缓存,结果删除失败导致缓存是旧值。

  • 多线程并发写数据时,缓存更新被覆盖。

✅ 解决方案

  • 先删除缓存,再更新数据库(防止“读旧数据”)

  • 延迟双删策略:更新数据库后延迟再删一次缓存

    // 1. 删除缓存
    redis.del(key);// 2. 更新数据库
    db.update(data);// 3. 延迟再删(可用线程池延迟执行)
    Thread.sleep(1s);
    redis.del(key);
    
  • 消息队列异步更新缓存:更新后推送事件,由缓存服务更新


✅ 总结口诀

为了方便记忆,这里提供一句口诀:

穿透找不到,击穿太热闹,雪崩全失效,不一致顺序错。


📌 结语

缓存是提高系统性能的重要手段,但随之也带来了种种挑战。我们在设计系统时,应该对上述四种情况都有应对策略,避免因缓存问题造成服务雪崩、数据异常甚至系统崩溃。

欢迎收藏本篇文章,作为缓存容错设计的备查手册。🚀

http://www.xdnf.cn/news/4284.html

相关文章:

  • 依赖注入详解与案例(前端篇)
  • 基于ASP.NET+MySQL实现待办任务清单系统
  • 信奥赛CSP-J复赛集训(DP专题)(37):P4170 [CQOI2007] 涂色
  • [学习]RTKLib详解:rtkcmn.c与rtkpos.c
  • 学习Python的第二天之网络爬虫
  • cephadm部署ceph集群
  • php案列
  • QML ProgressBar控件详解
  • G919-GAS软件 JSON格式数据通讯协议-阵列数据解析
  • SQLark可以支持PostgreSQL了,有哪些新功能?
  • C++ Avl_Tree
  • 239. 滑动窗口最大值
  • yolo训练用的数据集的数据结构
  • RPA自动化:开启智能流程新时代
  • OpenCV 图形API(77)图像与通道拼接函数-----对图像进行几何变换函数remap()
  • 面试常问系列(一)-神经网络参数初始化-之-softmax
  • java springboot解析出一个图片的多个二维码
  • 软考-软件设计师中级备考 13、刷题 数据结构
  • k8s node soft lockup (内核软死锁) 优化方案
  • python3使用:macOS上通过Homebrew安装pip库
  • linux 如何防止内存碎片化?
  • C#中不能通过new关键字创建实例的情况
  • conda虚拟环境相关操作
  • LeetCode 热题 100 39. 组合总和
  • Jetpack Compose 自定义 Slider 完全指南
  • QT键盘触发按钮
  • laravel 12 监听syslog消息,并将消息格式化后存入mongodb
  • 深度解析:2D 写实交互数字人 —— 开启智能交互新时代
  • API 开发实战:基于京东开放平台的实时商品数据采集接口实现
  • 【25软考网工】第五章(6)TCP和UDP协议、流量控制和拥塞控制、重点协议与端口