Java + Spring Boot + Redis技术栈,在实际使用缓存时遇到 缓存击穿、缓存穿透、缓存雪崩 - 详解

news/2025/12/1 12:38:25/文章来源:https://www.cnblogs.com/gccbuaa/p/19292356

针对 Java + Spring Boot + Redis 技术栈,在实际使用缓存时遇到 缓存击穿、缓存穿透、缓存雪崩 是非常常见的,下面我会结合这个技术组合,给出 具体原因、问题场景、以及对应的解决方案和代码/配置示例,帮助你在实际项目中更好地应对这些问题。


一、缓存击穿(Cache Breakdown)—— 热点 key 突然失效,大量请求直达数据库

场景举例

比如“热门商品详情”(如 iPhone 15 商品ID=1001)被缓存,且缓存 key product:1001 设置了过期时间,假设是 30 分钟。当这个 key 恰好在某个高峰期过期,而又有大量用户同时访问该商品,就会导致 大量请求穿透到数据库,造成 DB 压力剧增。

✅ 解决方案(Spring Boot + Redis)

方案1:使用 互斥锁(分布式锁),只允许一个线程重建缓存

使用 Redis 的 SETNX(或 Redisson 的分布式锁)来实现:

依赖(如果使用 Redisson,推荐):
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>3.x.x</version>
</dependency>
示例代码(伪代码逻辑,简化版):
@Autowired
private RedisTemplate<String, Object> redisTemplate;@Autowiredprivate RedissonClient redissonClient; // 使用 Redisson 分布式锁public Product getProductById(Long id) {String cacheKey = "product:" + id;// 1. 先查缓存Product product = (Product) redisTemplate.opsForValue().get(cacheKey);if (product != null) {return product;}// 2. 缓存没有,尝试获取锁RLock lock = redissonClient.getLock("lock:product:" + id);try {// 尝试加锁,最多等10秒,锁持有15秒后自动释放if (lock.tryLock(10, 15, TimeUnit.SECONDS)) {try {// 双重检查,可能其他线程已经重建好缓存product = (Product) redisTemplate.opsForValue().get(cacheKey);if (product != null) {return product;}// 3. 查数据库product = productRepository.findById(id).orElse(null);if (product != null) {// 4. 写入缓存,设置过期时间,比如30分钟redisTemplate.opsForValue().set(cacheKey, product, 30, TimeUnit.MINUTES);} else {// 可选:缓存空对象,防止穿透redisTemplate.opsForValue().set(cacheKey, new NullProduct(), 5, TimeUnit.MINUTES);}return product;} finally {lock.unlock();}} else {// 没抢到锁,稍后重试或者返回默认/错误信息Thread.sleep(100);return getProductById(id); // 简单重试,生产环境建议限流或返回兜底数据}} catch (InterruptedException e) {Thread.currentThread().interrupt();throw new RuntimeException("获取锁失败", e);}}

⚠️ 注意:生产环境中应做好重试机制、超时控制与降级策略,不要轻易重试或递归调用。

方案2:逻辑过期 + 后台刷新(适合读多写少)

不设置真正的过期时间,而是在 value 里保存一个过期时间字段,定时检查并异步刷新缓存。


二、缓存穿透(Cache Penetration)—— 查询不存在的数据,绕过缓存

场景举例

用户请求了一个 不存在的商品 ID(比如 999999999),这个 ID 在数据库中根本不存在,所以每次查询:

  • 缓存中没有
  • 数据库中也没有
    → 导致每次都打到数据库,如果有人恶意发起大量此类请求,DB 就会扛不住。

✅ 解决方案

方案1:缓存空对象(Null Object Pattern)

当查询数据库发现数据不存在时,仍然将一个特殊的标记(如 null 或自定义的 NullProduct 对象)存入 Redis,并设置较短的过期时间,例如 3~5 分钟,避免频繁查库。

代码片段(接上面):
if (product == null) {
// 缓存空对象,防止穿透
redisTemplate.opsForValue().set(cacheKey, new NullProduct(), 5, TimeUnit.MINUTES);
return null;
}

其中 NullProduct 是你自定义的一个类,代表“空结果”,可用于前端展示或逻辑判断。

方案2:使用 布隆过滤器(Bloom Filter)

在查询数据库之前,先用布隆过滤器判断该 key(如商品 ID)是否 可能存在,如果布隆过滤器判断“一定不存在”,则直接返回,无需查缓存和数据库。

如何集成布隆过滤器?

可以使用 Google 的 Guava BloomFilter(适合单机)或 RedisBloom(适合分布式,需引入 Redis 模块)。

简易示例(Guava,适合简单场景):
// 初始化时将所有合法商品ID加入布隆过滤器
BloomFilter<Long> bloomFilter = BloomFilter.create(Funnels.longFunnel(),1000000,  // 预期元素数量0.01      // 误判率);// 添加合法IDbloomFilter.put(1001L);bloomFilter.put(1002L);// 查询时先判断if (!bloomFilter.mightContain(id)) {return null; // 一定不存在}// 再查缓存、查DB

⚠️ 生产环境中若数据量大、分布式部署,建议使用 RedisBloom 模块(需 Redis 支持)或自建布隆过滤器服务。


三、缓存雪崩(Cache Avalanche)—— 大量缓存同时失效 / Redis 宕机

场景举例

假如你给所有商品缓存都设置了 过期时间为 30 分钟,并且这些 key 的过期时间基本一致,那么在 某个 30 分钟的整点时刻,大量缓存同时失效,导致大量请求直接打到数据库,造成服务崩溃。

或者,Redis 宕机或网络抖动,也会导致缓存完全不可用,所有请求直连 DB。

✅ 解决方案

方案1:设置 随机过期时间,避免同时失效

不要所有 key 都设置相同的过期时间,比如:

// 原始:30分钟
// 改为:30分钟 + 随机0~10分钟
int expireTime = 30 + new Random().nextInt(10);
redisTemplate.opsForValue().set(cacheKey, product, expireTime, TimeUnit.MINUTES);

这样可以有效让缓存 错开失效时间,避免同时雪崩。

方案2:多级缓存策略

  • 一级缓存:本地缓存(如 Caffeine、Guava Cache)
  • 二级缓存:Redis

即使 Redis 出现问题,本地缓存依然能挡住一部分流量。

示例(Caffeine 作为本地缓存):
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
LoadingCache<Long, Product> localCache = Caffeine.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES).maximumSize(10_000).build(this::loadProductFromRedisOrDB);

方案3:Redis 高可用

  • 使用 Redis 哨兵(Sentinel)集群(Cluster) 模式,提高缓存可用性,防止单点故障。
  • 如果 Redis 宕机,应有 降级策略(比如返回旧数据、默认值、错误提示等)。

方案4:熔断降级(如 Sentinel、Hystrix)

当数据库压力过大或 Redis 不可用时,可以快速失败或返回兜底内容,避免服务雪崩。


四、其他增强措施(推荐)

✅ 缓存预热

在系统启动时或低峰期,提前将热点数据加载到缓存中,避免冷启动时大量请求直接访问数据库。

✅ 监控与报警

  • 使用 Spring Boot Actuator + Prometheus + Grafana 监控:
    • 缓存命中率
    • Redis 响应时间、QPS
    • 数据库负载
  • 设置报警规则,如缓存未命中率过高、Redis 连接失败等。

✅ 接口限流

对于高频访问接口,可使用 Sentinel、RateLimiter、Redis + Lua 实现接口限流,防止恶意刷接口。


总结(Java + Spring Boot + Redis 应对三大问题)

问题原因简述推荐解决方案(Spring Boot + Redis)
缓存击穿热点 key 突然失效,大量请求直达 DB互斥锁(Redisson)、逻辑过期、后台刷新、双重检查锁
缓存穿透查询不存在的数据,绕过缓存直连 DB缓存空对象(Null Object)、布隆过滤器(Guava / RedisBloom)、参数校验
缓存雪崩大量 key 同时失效 / Redis 宕机设置随机过期时间、多级缓存(Caffeine + Redis)、Redis 高可用、熔断降级、缓存预热

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/982846.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

洛谷题单指南-组合数学与计数-P3214 [HNOI2011] 卡农

原题链接:https://www.luogu.com.cn/problem/P3214 题意解读:从数字1~n组成的所有非空子集中,选m个子集组成集合T,要求集合T里所有子集的数字都出现偶数次,请所有T的方案数。 解题思路: 数字1~n组成的非空子集一…

2025环保艺术漆头部品牌TOP5权威推荐:剖析艺术漆市场现

随着消费者对家居美学与环保健康的需求升级,艺术漆市场近年来呈现爆发式增长。2024年数据显示,国内艺术漆市场规模突破300亿元,年增速达35%,其中环保型艺术漆占比超60%。然而,市场扩张也伴随痛点:28%的代理商反馈…

2025年十大比较好的钢结构楼梯厂家排行榜,推荐钢结构楼梯工

为帮企业与个人高效锁定适配需求的钢结构楼梯合作伙伴,避免选型走弯路,我们从技术落地能力(如结构稳定性、定制化实现度)、设计美学水准(含空间适配性、艺术感呈现)、全周期服务质量(覆盖前期测量到后期维保)及…

2025烤蓝铁皮打包带源头厂家TOP5权威推荐:优质生产商甄

在工业物流与重型货物运输领域,烤蓝铁皮打包带因高强度、防锈性与环保回收特性,成为钢材、机械、木材等重型货物捆扎的核心材料。2024年数据显示,其市场需求年增速达32%,但30%的投诉集中在边缘锋利致工伤、工具依赖…

钢结构楼梯厂家TOP5权威推荐:知名厂家深度测评,甄选不错工

在现代建筑空间设计中,钢结构楼梯因兼具力学稳定性与艺术可塑性,成为商业地产、家装及公共场馆的核心选型之一。2024年数据显示,国内定制化钢结构楼梯市场规模突破60亿元,年增速达32%,但31%的客户投诉集中在落地变…

Win11 + Ubuntu 双系统安装流程(暗夜精灵) - Daniel

本文介绍如何有win11系统的电脑上再安装Ubuntu的操作系统,除系统安装外,还内含如何解决BitLocker蓝屏、引导丢失后无法进入系统、启动界面美化等遇到的问题。简介 本片博客主要记录我个人在 Windows11 基础上安装 Ub…

import加载包和模块的机制原理

import加载包和模块的机制原理import加载包和模块的机制原理 一、核心概念:模块与包的本质 1. 模块:单个.py文件就是模块 Python中模块(Module)无需显式声明,任何以.py为后缀的文件都是一个模块,模块名即为文件名…

模型推理如何利用非前缀缓存 - 详解

模型推理如何利用非前缀缓存 - 详解2025-12-01 12:25 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !imp…

区域选择组件(PC)

从零到一:开发高性能的PC端多选区域选择组件 在招聘需求发布场景中,常常需要选择多个地址,但组件库自带的级联选择往往存在局限性:只能选择到具体城市、无法多选父级地区、展示不够直观等。今天我将带大家从零开始…

Wyrm + MNE 工具链完整介绍

🧠 Wyrm + MNE 工具链完整介绍 🧩 一句话总结 MNE = 科研级 EEG 工具(可视化、预处理、ICA) Wyrm = 工程级 BCI 工具箱(Epoch、CSP、快速特征处理) 两者组合:MNE 负责“干净数据”,Wyrm 负责“工程特征 + 训…

CF767E-Change-free

CF767E-Change-free 题目大意 你接下来 \(n\) 天回去食堂吃饭,而且现在你已经决定好了吃什么,所以你在接下来的第 \(i\) 天,花费 \(c_i\) 元。 交易时只允许使用 \(1\) 元的硬币和 \(100\) 元的纸币,你初始有 \(m\…

哈尔滨装修安装工程企业TOP5权威推荐:助力洁净空间品质升级

在医疗与工业领域的专业化建设进程中,企业对合规化、高洁净度的装修安装工程需求持续攀升。2024年黑龙江省医疗洁净工程市场规模突破20亿元,年增速达32%,但行业调研显示,35%的客户投诉集中在洁净度不达标、空间布局…

炼油设备厂家TOP5权威推荐:甄选靠谱大型厂家,赋能工业固废

工业固废资源化利用需求攀升,2024年相关设备市场规模突破360亿元,年增速达32%,但中小企业采购常遇坑:初期成本高致资金压力大、设备工况适配性差效率骤降、操作复杂缺运维团队、与生产衔接不畅影响产能。本榜单基于…

WMS 仓库管理系统怎么选择?

推荐排名①:首选 — 北京鸿链科技有限公司(鸿链科技) 公司介绍 北京鸿链科技有限公司(简称「鸿链科技」)成立于2016年9月,由招商局集团与中国外运联合孵化,是国内领先的仓储物流软件SaaS平台服务商。其核心产品…

VW/Audi MQB All Keys Lost: Hassle-Free SYNC Data Calculations with Xhorse VVDI Autel

Solving the MQB All Keys Lost Dilemma: SYNC Data Solutions for VW & Audi The Challenge: All Keys Lost for VW/Audi MQB Models For European and American automotive repair shops and car owners, a frus…

快捷键和Dos命令

Ctrl+c负责 Ctrl+v粘贴 Ctrl+a全选 Ctrl+x剪切 Ctrl+z撤销 Ctrl+s保存 Ctrl+y复原 win+r 运行 win+e 打开我的电脑 Ctrl+shift+esc任务管理器 shift+delelte永久删除 Alt+F4 关闭窗口 打开cmd方式开始-系统-命令提示符…

2025年哈尔滨十大有名的装修安装工程公司推荐,口碑不错的装

在医疗与工业领域,洁净空间的装修安装工程是保障安全运营与高效生产的核心基石。哈尔滨净朗净化科技有限公司作为本地洁净工程领域的标杆企业,始终以科创之力破解行业痛点。面对市场上良莠不齐的装修安装工程服务,如…

2025年度全屋定制品牌生产厂哪家更值得选?5大实力厂商排行

为帮助装修业主、家居经销商精准锁定适配需求的全屋定制生产厂,避开报价虚高、板材以次充好、落地效果偏差等坑,本文从生产实力(工业4.0标准、供应链管控)、产品品质(环保等级、工艺细节)、服务保障(质保政策、…

列表弹窗实现方案整理

列表弹窗实现方案整理 在Web应用开发中,列表页的编辑和新增功能是非常常见的交互场景。通常我们会通过点击"新增"或"编辑"按钮,打开一个弹窗(Modal/Dialog)来展示表单信息,用户填写或修改数据…

硬盘检测修复工具!实时监测硬盘健康度、温度、还能修复扇区!

如何检测SSD(固态硬盘)是不是二手(翻新)的?有检测固态硬盘是否损坏的工具吗?坏道检测对硬盘伤害大吗?安装系统时检测不到固态硬盘怎么办?有检测固态硬盘是否损坏的工具吗?如何检测SSD(固态硬盘)是不是二手(…