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

说说什么是Redis缓存击穿、缓存穿透、缓存雪崩?

大家好,我是锋哥。最近不少粉丝问锋哥什么是Redis缓存击穿、缓存穿透、缓存雪崩?今天锋哥来总结下,大家可以参考。

2026年,锋哥又开始收Java学员了!

Redis作为高性能的键值存储解决方案,广泛应用于缓存机制中。然而,在其实际使用中,开发者们常常会遇到“缓存击穿”、“缓存穿透”和“缓存雪崩”这几个概念。为了解释这些问题,并提供相应的解决方案,本文将结合Java代码进行说明。

一、缓存击穿

定义

缓存击穿是指在高并发情况下,某个热点数据的缓存失效,导致大量请求同时访问数据库,从而对数据库造成巨大的压力。

场景

假设某个用户的数据在缓存中失效,且每个请求同时访问数据库,数据库可能因此崩溃。

解决方案

使用互斥锁(例如,用Redis的SETNX命令),确保只有一个请求去查询数据库。

Java代码示例
import redis.clients.jedis.Jedis;public class CacheTest {private Jedis jedis = new Jedis("localhost");public String getData(String key) {String data = jedis.get(key);if (data == null) {// 使用分布式锁String lockKey = "lock:" + key;String lockValue = String.valueOf(System.currentTimeMillis() + 10000); // 10秒锁if (jedis.setnx(lockKey, lockValue) == 1) {try {// 此处模拟数据库查询data = queryDatabase(key);jedis.set(key, data);} finally {jedis.del(lockKey); // 释放锁}} else {// 等待一段时间后重试Thread.sleep(100);return getData(key);}}return data;}private String queryDatabase(String key) {// 模拟数据库查询return "data_for_" + key; // 返回数据库中的数据}}

二、缓存穿透

定义

缓存穿透指的是请求的数据在缓存和数据库中均不存在,导致每次请求都直达数据库,造成数据库的负担。

场景

攻击者可能发送大量请求,访问不存在的ID,导致数据库处理大量无效请求。

解决方案

引入布隆过滤器,提前过滤不存在的请求,或者对不存在的数据进行空对象缓存。

Java代码示例
import redis.clients.jedis.Jedis;public class CacheTest {private Jedis jedis = new Jedis("localhost");public String getData(String key) {// 布隆过滤器模拟if (!isKeyValid(key)) {return null; // 过滤掉无效请求}String data = jedis.get(key);if (data == null) {// 查询数据库data = queryDatabase(key);if (data == null) {// 将空对象缓存jedis.set("empty:" + key, ""); // 设置空对象缓存} else {jedis.set(key, data);}}return data;}private boolean isKeyValid(String key) {// 模拟布隆过滤器的有效性判断return key.matches("^[a-zA-Z0-9]+$"); // 仅允许字母和数字}private String queryDatabase(String key) {// 模拟数据库查询return "data_for_" + key; // 返回数据库中的数据}}

三、缓存雪崩

定义

缓存雪崩是指在某个时间点,大量缓存数据同时失效,导致缓存不可用,所有请求直达数据库。

场景

例如,若多个缓存的过期时间设定为相同,到了同一时刻,所有缓存都失效,直接向数据库发送请求。

解决方案

设置不同的过期时间,避免同时失效。

Java代码示例
import redis.clients.jedis.Jedis;public class CacheTest {private Jedis jedis = new Jedis("localhost");public String getData(String key) {String data = jedis.get(key);if (data == null) {// 查询数据库data = queryDatabase(key);if (data != null) {// 设置不同过期时间,使用随机时间int randomExpireTime = 60 + (int)(Math.random() * 60); // 随机60秒到120秒jedis.setex(key, randomExpireTime, data); // 设置过期时间}}return data;}private String queryDatabase(String key) {// 模拟数据库查询return "data_for_" + key; // 返回数据库中的数据}}

最后总结下,Redis在缓存中能够有效提升系统性能,但在实际应用中,缓存击穿、缓存穿透和缓存雪崩是不可忽视的问题。通过上述的示例和解决方案,开发者可以基于Java和Redis构建更加稳定和高效的缓存机制,提高系统的可靠性和响应速度。希望本篇文章能为大家提供帮助和启发。

http://www.jsqmd.com/news/279017/

相关文章:

  • 全网都在推 Claude Code,但只有这篇文章教你如何“真正”能用
  • 基于深度学习YOLOv10的道路交通信号检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)
  • SpringBoot如何对接第三方系统?
  • AI跑得太快,基础设施却拖后腿?可组合+自主式AI正在重塑企业底座
  • 面试官:多线程事务怎么回滚?说用@Transactional可以回去等通知了!
  • 基于深度学习YOLOv10的铁路轨道缺陷检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)
  • 基于深度学习YOLOv10的钢铁腐蚀生锈检测系统(YOLOv10+YOLO数据集+UI界面+Python项目源码+模型)
  • async Task方法返回null会发生什么?(C#异步编程避坑指南)
  • Spring和SpringMVC为什么需要父子容器?
  • Emotion2Vec+ Large部署卡顿?3步解决显存不足问题实战案例
  • 自定义表单源码系统如何助力企业实现多场景高效运营
  • cv_resnet18_ocr-detection降本方案:低成本GPU部署节省60%
  • 基于深度学习的道路交通信号检测系统(YOLOv8+YOLO数据集+UI界面+Python项目源码+模型)
  • fft npainting lama混合精度训练配置:AMP加速收敛技巧
  • 多功能表单源码系统的核心优势 带完整的搭建部署教程
  • 十位营销领导者谈2026年哪些将延续,哪些将淘汰,哪些将规模化
  • unet人像卡通化更新日志:v1.0功能全面解读
  • CAM++能否做语音克隆检测?反欺诈应用探索
  • 多功能表单源码系统,解决信息收集、客户预约与线上收款的综合型工具
  • Open-AutoGLM安全吗?敏感操作确认机制深度解析
  • 如何利用C++23的模块化系统重构百万行代码?真实案例分享
  • 如何提高召回率?FSMN-VAD敏感度参数调整指南
  • Qwen3-0.6B从零开始:新手开发者部署全流程详解
  • 为什么你的fwrite没写入?深度解读C语言二进制写入陷阱
  • 紧急警告:C++项目中出现undefined reference?立即检查这6个关键点!
  • 免费文献检索网站推荐:实用资源汇总与高效使用指南
  • OpenACC介绍
  • 学习干货_从迷茫到前行:我的网络安全学习之路
  • 【C++异步编程核心技术】:深入掌握std::async的5种高效用法与陷阱规避
  • C++23新特性全曝光(一线大厂已全面启用)