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

【Redis】终极缓存四连杀:缓存预热、缓存击穿、缓存穿透、缓存雪崩,真的懂了吗?

🎯 前言

你有没有遇到过这种情况:

  • 刚上线的新功能,所有用户一窝蜂冲进来,服务器被打爆?🚀(缓存预热)
  • 某个热点数据突然失效,数据库压力瞬间飙升,仿佛遭遇 DDoS?🔥(缓存击穿)
  • 有人恶意查询不存在的数据,导致数据库扛不住,全站崩溃?💀(缓存穿透)
  • 缓存整体崩溃,数据库直接被“屠杀”,网站直接GG?❄️(缓存雪崩)

这四大问题,是缓存系统的 噩梦级挑战,稍有不慎,就会导致网站宕机、业务瘫痪!

今天,我们就来揭秘这四个“终极杀手”,看看它们是什么,怎么解决,以及如何让你的缓存系统更加稳如老狗!🐶


一、缓存预热——让缓存从“0”到“1”

1. 什么是缓存预热?

缓存预热(Cache Warming) 就是 在系统启动或数据更新后,提前将常用数据加载到缓存,避免用户第一次访问时 直接打数据库,导致查询慢甚至数据库崩溃。

📌 打个比方: 想象你开了一家 网红奶茶店,门口排着 1000 个人!

  • 没做预热:第一个人来了,你才去煮珍珠、泡茶,结果一杯奶茶 10 分钟,用户等得要骂娘了。
  • 做了预热:提前煮好珍珠、泡好奶茶,用户一来就能迅速出杯,丝滑流畅!

高并发场景下,如果没有缓存预热,系统刚上线,所有请求都会打数据库,瞬间压垮数据库。

2. 解决方案

方案 1:启动时自动加载

  • 在 服务启动时,批量查询数据库的热门数据,放入缓存。
  • 适用于 数据变化不频繁,比如商品详情、系统配置。

方案 2:定时预热

  • 定时任务(CRON)每隔一段时间加载最新数据,适用于数据有一定变动的场景,比如 每日热销商品榜单。

方案 3:用户触发预热

  • 第一次查询数据库后,主动将数据写入缓存,适用于 数据更新不定时 的情况。

二、缓存击穿——“热点数据”消失的瞬间

1. 什么是缓存击穿?

缓存击穿(Cache Breakdown)指的是 某个热点 Key 在缓存中过期,短时间内大量请求打到数据库,导致数据库压力骤增甚至崩溃

感觉 Cache Breakdown 翻译为 缓存击穿并不好理解,理解为缓存瘫痪、崩溃反而更加贴近意思。

📌 打个比方: 你在天猫秒杀抢购一台 iPhone 15,结果查询 iphone_15_stock这个缓存 Key 失效了,所有用户的请求都去查询数据库,瞬间压垮 MySQL。

2. 解决方案

方案 1:设置热点数据不过期

  • 永不过期(TTL = -1),让热点数据一直在缓存中。
  • 适用于 热点数据稳定(如商品信息、排行榜)。

方案 2:使用“互斥锁”控制访问

  • 当缓存失效时,第一个查询的线程 加锁,查询数据库并更新缓存,其它线程等待:
if (redis.get("iphone_15_stock") == null) {if (redis.setnx("lock:iphone_15", 1)) { // 加锁int stock = db.query("SELECT stock FROM goods WHERE id=15");redis.set("iphone_15_stock", stock, 60); // 重新写缓存redis.del("lock:iphone_15"); // 释放锁} else {Thread.sleep(50); // 等待retry();}
}

方案 3:提前刷新缓存

  • 定时任务 在缓存快过期前 提前更新缓存,确保热点 Key 始终有效。

三、缓存穿透——数据库被“恶意”干爆

1. 什么是缓存穿透?

缓存穿透(Cache Penetration)指的是 查询一个根本不存在的数据,由于缓存没有该 Key,导致每次查询都直击数据库,造成数据库压力暴增!

📌 打个比方

  • 你去奶茶店点 唱跳rap特饮”,结果店员翻遍菜单都找不到,每次都要去后厨确认…… 数据库 = 被白嫖爆破!

在现实中,缓存穿透 通常由攻击者恶意构造请求,查询不存在的订单、用户 ID,导致数据库直接爆炸。

2. 解决方案

方案 1:缓存空对象

  • 如果数据库查询为空,仍然缓存一个空值,防止后续请求继续打数据库:
Object value = redis.get("user:99999");
if (value == null) {User user = db.query("SELECT * FROM user WHERE id=99999");if (user == null) {redis.set("user:99999", "", 60); // 缓存空对象 60 秒}
}

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

  • 使用布隆过滤器 维护一个 所有有效 Key 的集合,查询前先判断是否存在:
if (!bloomFilter.contains("user:99999")) {return null; // 直接返回,不查询数据库
}

方案 3:限流 + 黑名单

  • 对 IP 进行限流,防止某个 IP 短时间内大量请求 无效 Key,对恶意 IP 封禁处理。

方案 4:接口层增加校验

  • 用户鉴权、参数校验(请求参数是否合法、请求字段是否不存在等等);

四、缓存雪崩——比缓存击穿更致命

1. 什么是缓存雪崩?

缓存雪崩(Cache Avalanche)指的是 大量缓存 Key 在同一时间过期,导致请求全部打到数据库,数据库直接宕机。或者缓存服务出现故障,导致大量请求直接访问数据库,最终导致数据库崩溃的现象。

📌 打个比方

  • 你经营一个电商网站,给所有商品的缓存都设置了 同样的过期时间(比如 1小时)。
  • 结果,1 小时后 所有缓存同时失效,数据库瞬间被打爆,服务器直接跪了!

2. 解决方案

方案 1:给 Key 过期时间加随机数

  • 让不同 Key 的过期时间 错开,避免同一时间大面积失效:
redis.set("goods:123", data, 3600 + random(600)); // 1 小时 + 0~10 分钟随机时间

方案 2:分布式缓存架构

  • 使用 Redis Cluster,数据分散到多个节点,避免单点压力。

方案 3:双层缓存

  • 让 多个 Redis 共同承担缓存,防止单点崩溃。
  • 原理:使用两个缓存层,一个为主缓存(一级缓存),一个为从缓存(二级缓存)。数据首先存储在主缓存中,同时也在从缓存中有一份备份,但从缓存的过期时间设置得比主缓存长。当主缓存数据过期或者出现问题时,可以从从缓存中获取数据,为更新主缓存争取时间。
  • 示例:在一个金融交易系统中,对于股票价格信息,可以采用双缓存机制。主缓存中的股票价格数据过期时间较短,例如设置为 1 分钟,从缓存中的过期时间设置为 5 分钟。当主缓存中的股票价格数据过期时,系统可以先从从缓存中获取价格信息,同时更新主缓存。

🎯 总结

问题触发原因解决方案
缓存预热缓存刚上线,没有数据启动时加载、定时任务预热
缓存击穿热点 Key 失效,大量请求打数据库热点 Key 不过期、互斥锁、提前刷新
缓存穿透查询不存在的数据,导致数据库被打爆缓存空对象、布隆过滤器、限流黑名单
缓存雪崩大量缓存同时失效,数据库被压垮过期时间加随机值、分布式缓存、双层缓存

🚀 掌握这些缓存优化技巧,让你的 Redis 高并发系统更稳更快,拒绝崩溃!

相关文章:

【Redis】终极缓存四连杀:缓存预热、缓存击穿、缓存穿透、缓存雪崩,真的懂了吗?

🎯 前言 你有没有遇到过这种情况: 刚上线的新功能,所有用户一窝蜂冲进来,服务器被打爆?🚀(缓存预热)某个热点数据突然失效,数据库压力瞬间飙升,仿佛遭遇 DD…...

Java Spring MVC (2)

常见的Request Controller 和 Response Controller 的区别 用餐厅点餐来理解 想象你去一家餐厅吃饭: Request Controller(接单员):负责处理你的点餐请求,记录你的口味、桌号等信息。Response Controller&#xff08…...

Linux网络相关内容与端口

网络相关命令 ping命令测试连接状态 wget命令:非交互式文件下载器,可以在命令行内下载网络文件 使用ctrlc可以中止下载 curl命令:可以发送http网络请求,用于文件下载、获取信息等 其实和浏览器打开网站一样,cu…...

Spring Boot + MyBatis + MySQL:快速搭建CRUD应用

一、引言 1. 项目背景与目标 在现代Web开发中,CRUD(创建、读取、更新、删除)操作是几乎所有应用程序的核心功能。本项目旨在通过Spring Boot、MyBatis和MySQL技术栈,快速搭建一个高效、简洁的CRUD应用。我们将从零开始&#xff…...

日新F1、瑞研F600P 干线光纤熔接(熔接损耗最大0.03DB)

Ⅰ. 设备特性对比与实测验证 1. 日新F1(两马达)极限参数 切割角度:必须≤0.3(双边累计误差<0.6) ▶ 实测案例:切割0.35时,损耗波动达0.05-0.08dB(超干线标准&#xff09…...

分布式网络

分布式网络(Distributed Network)指的是一种计算机网络架构,其中计算资源(计算、存储、数据处理等)分布在多个物理或逻辑上的节点上,而不是集中在单一的服务器或数据中心中。这种架构的主要目标是提高系统的…...

【招聘精英】

我们公司是一个位于石家庄的一个科技型新型技术公司。主要做人力资源、用工、科技等方面。 有意向回石家庄的或者已经在石家庄的技术大咖、软件大牛、产品大佬、UI大神可以来了解一下。 现在招聘 高级前端开发 高级java开发 其他岗位也可以联系。 有意向的朋友可以私信我。 -…...

ESP8266 NodeMCU 与 Atmega16 微控制器连接以发送电子邮件

NodeMCU ESP8266 AVR 微控制器 ATmega16 的接口 Atmega16 是一款低成本的 8 位微控制器,比以前版本的微控制器具有更多的 GPIO。它具有所有常用的通信协议,如 UART、USART、SPI 和 I2C。由于其广泛的社区支持和简单性,它在机器人、汽车和自动化行业有广泛的应用。 Atmega1…...

MongoDB用户管理和复制组

用户管理 1、建用户时,use到的库就是此用户的验证库 2、登录时必须明确指定验证库才能登录 3、通常管理员用的验证库是admin,普通用户的验证库一般是所管理的库设置为验证库 4、如果直接登录到数据库,不进行use(示例&#xff…...

GoLang的select是什么?在什么时候场景下用

在 Go 语言中,select 是专门用于处理通道(Channel)多路复用的关键字,它可以同时监听多个通道的读写操作,并根据就绪的通道执行对应的逻辑。以下是 select 的用法和典型应用场景: 一、基本用法 select 语法…...

SQLAlchemy系列教程:集成Pydantic增强数据处理能力

本教程介绍如何将Pydantic用于数据验证,SQLAlchemy用于数据库操作,从而通过强大的数据处理能力增强Python应用程序。 介绍 在现代web开发中,确保数据的有效性和完整性至关重要。Pydantic和SQLAlchemy是两个功能强大的Python库,可…...

【数据结构初阶】---堆的实现、堆排序以及文件中的TopK问题

1.树的概念及结构 1.1树的概念 树是一种非线性的数据结构,它是由n(n>0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 有一个特殊的结点&…...

python中httpx库的详细使用及案例

文章目录 1. 安装 httpx2. 同步请求3. 异步请求4. 高级功能5. 错误处理6. 配置客户端7. 结合 Beautiful Soup 使用8. 示例:抓取并解析网页9. 注意事项httpx 是一个现代化的 Python HTTP 客户端库,支持同步和异步请求,功能强大且易于使用。它比 requests 更高效,支持 HTTP/2…...

IP,MAC,ARP 笔记

1.什么是IP地址 IP 地址是一串由句点分隔的数字。IP 地址表示为一组四个数字,比如 192.158.1.38 就是一个例子。该组合中的每个数字都可以在 0 到 255 的范围内。因此,完整的 IP 寻址范围从 0.0.0.0 到 255.255.255.255。 IP 地址不是随机的。它们由互…...

【记录】Python3|Linux下安装Virtualenv和virtualenvwrapper用于处理虚拟环境

之前写过一篇Anaconda的:【安装】Python3|Windows下安装Anaconda、pytorch,以及修改pip默认安装路径_anaconda pip修改安装的包路径-CSDN博客 还写过一篇专门讲所有虚拟环境的:【记录】环境|Ubuntu18.04 Python 开发环…...

VSTO(C#)Excel开发3:Range对象 处理列宽和行高

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...

Selenium库打开指定端口(9222、9333等)浏览器【已解决!!!】

就是在写动态爬虫爬取数据的过程中,如果用selenium的话,有一个缺点,就是当我们去测试一个网站能不能爬取,它都会重新换端口打开一个浏览器,不会使用上一次使用的浏览器,在实际使用过程中这样调试很烦&#…...

Redis在人员管理系统中的应用示例

用户会话管理 场景:用户登录后存储会话信息,支持多服务器共享 实现: 用户登录成功后,生成唯一Token(如JWT),作为Redis的Key Value存储用户ID、角色、权限等信息,设置过期时间&…...

蓝桥杯备考:倍增算法详解

如果我们想暴力求解的话&#xff0c;我们的时间复杂度是O&#xff08;N&#xff09;b最大是10的9次方&#xff0c;这时候我们一定会超时 #include <iostream> using namespace std;typedef long long LL; LL a,b,p;LL ret 1; int main() {cin >> a >> b &g…...

安徽省考计算机专业科目2025(持续更新)

目录 第一部分 计算机科学技术基础 第一章 计算机及其应用基础知识 1.1 计算机的特点、分类及其应用 1.2 信息编码与数据表示&#xff1b;数制及其转换方法&#xff1b;算术运算和逻辑运算的过程 第一部分 计算机科学技术基础 第一章 计算机及其应用基础知识 1.1 计算机…...

PostgreSQL、SQL Server和MySQL数据库性能调优与故障排除技术

通过结合具体技术特性与工具链的深度使用&#xff0c;可系统化提升数据库性能和稳定性。建议根据实际负载特征制定监控-分析-优化的闭环管理流程。 数据库技术&#xff1a; PostgreSQL 13&#xff1a;逻辑复制、分区表、并行查询、监控工具&#xff08;如pg_stat_statements、…...

【贪心算法2】

力扣122.买卖股票最佳时机Ⅱ 链接: link 思路 要求最大利润&#xff0c;可以分解成子问题求解&#xff0c;在最低价格买入&#xff0c;最高价格卖出。 假如第0天价格最低&#xff0c;第3天价格最高&#xff0c;利润prices[3] - pricnes[0], 可以将利润公式拆解成 (prices[3]…...

SQL经典查询

查询不在表里的数据&#xff0c;一张学生表&#xff0c;一张学生的选课表&#xff0c;要求查出没有选课的学生&#xff1f; select students.student_name from students left join course_selection on students.student_idcourse_selection.student_id where course_selecti…...

## DeepSeek写水果记忆配对手机小游戏

DeepSeek写水果记忆配对手机小游戏 提问 根据提的要求&#xff0c;让DeepSeek整理的需求&#xff0c;进行提问&#xff0c;内容如下&#xff1a; 请生成一个包含以下功能的可运行移动端水果记忆配对小游戏H5文件&#xff1a; 要求 可以重新开始游戏 可以暂停游戏 卡片里的水果…...

Flask 框架简介

Flask 框架简介 Flask 框架简介 Flask 框架简介 Flask 是一个 Python 微型网页开发框架。微型指明了 Flash 的核心是轻量级的&#xff0c;但是可以灵活扩展。下面的简单的例子要和一个数据库系统交互。Django附带了与最常见的数据库交互所需的库。另一方面&#xff0c;Flask允…...

【GoTeams】-5:引入Docker

本文目录 1. Dokcer-compose回顾下Docker知识编写docker-compose.yaml运行docker 2. 部署go服务编写dockerfile 1. Dokcer-compose 这里简单先用一下win版本的Docker&#xff0c;后期开发好了部署的时候再移植到服务器下进行docker部署。 输入命令docker-compose version 就可…...

将自定义vue组件加载在Mapbox或Maplibre的marker和popup上

1. 使用场景 在开发WebGIS应用时&#xff0c;我们常需要将自定义UI组件与地图元素结合。本文介绍如何将Vue组件集成到Mapbox/Maplibre的Marker标记点和Popup弹窗中&#xff0c;实现动态交互式的地图功能。 2. 为什么需要特殊处理&#xff1f; 在常规开发中我们大多的处理是 …...

定时任务和分布式任务框架

文章目录 一 Spring Task1.@Scheduled注解介绍2 基本用法(1)使用@EnableScheduling修饰启动类(2)创建定时任务的类(3)fixedDelay(4)fixedRate(5)cron3 执行多个任务4 设置异步执行5 @Async使用自定义线程池6 缺点二 xxl-job介绍架构图与其他任务调度平台的比较运行调…...

GB28181视频监控流媒体平台LiveGBS如何自定义收流端口区间以便减少收流端口数或解决端口冲突问题

LiveGBS GB28181流媒体服务在接收视频的时候默认是使用30000-30249&#xff0c; webrtc流播放端口区间默认是UDP的30250-30500区间。有些网络环境不方便开放这么大的端口区间&#xff0c;下面介绍下如何修改配置这个区间。 从页面上修改这个区间&#xff0c;端口区间尽量设置大…...

rabbitmq-amqp事务消息+消费失败重试机制+prefetch限流

1. 安装和配置 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency><dependency> <groupId>com.fasterxml.jackson.core</groupId> <arti…...