Redis缓存击穿实战解析,从原理到解决方案,科普缓存击穿与穿透区别

文章导读
Redis 缓存击穿是指热点 key 过期瞬间,大量并发请求直接冲击数据库,导致数据库压力骤增甚至宕机;而缓存穿透则是请求查询根本不存在的数据,缓存和数据库均无命中,请求直达数据库。解决击穿常用互斥锁或逻辑过期方案,确保同一时间只有一个线程重建缓存;解决穿透则采用缓存空值或布隆过滤器,拦截无效请求。两者核心区别在于数据是否存在于数据库以及是否针对热点 key。
📋 目录
  1. A Redis 缓存击穿、穿透、雪崩——一次性讲清楚,附 6 种解决方案
  2. B 【Redis】缓存三兄弟:穿透 / 击穿 / 雪崩,一文搞定定义、场景与实战方案
  3. C Redis 详解 (十二)------ 缓存穿透、缓存击穿、缓存雪崩
  4. D 【高并发实战】Redis 缓存穿透、击穿、雪崩:3 大经典的“炸库”危机与自救指南
  5. E FAQ
A A

Redis 缓存击穿是指热点 key 过期瞬间,大量并发请求直接冲击数据库,导致数据库压力骤增甚至宕机;而缓存穿透则是请求查询根本不存在的数据,缓存和数据库均无命中,请求直达数据库。解决击穿常用互斥锁或逻辑过期方案,确保同一时间只有一个线程重建缓存;解决穿透则采用缓存空值或布隆过滤器,拦截无效请求。两者核心区别在于数据是否存在于数据库以及是否针对热点 key。

Redis 缓存击穿、穿透、雪崩——一次性讲清楚,附 6 种解决方案

先搞懂三个问题到底是什么 很多人搞不清这三个问题的区别,我给你举个超市的例子,一秒钟就懂了。首先说缓存穿透:你开了个超市,有人天天来问你有没有奥特曼变身器卖,你仓库里根本没有这玩意儿,每次有人问你都得去仓库翻一遍,翻多了仓库管理员就烦了。对应到技术场景就是:用户请求的 key 根本不在缓存里,也不在数据库里,每次请求都直接打到数据库,请求多了数据库直接挂。然后是缓存击穿:超市里的可乐搞促销,1 块钱一瓶,几千人同时来买,刚好货架上的可乐卖完了,所有人都挤到仓库去抢,仓库门直接被挤爆。对应技术场景就是:某个热点 key 刚好过期了,这时候大量请求过来,缓存里没有,直接全打到数据库,数据库瞬间被打满。最后是缓存雪崩:超市货架上的所有商品今天统一到期,几千人同时来买东西,发现货架全空了,所有人都冲到仓库去,仓库直接瘫痪。对应技术场景就是:大量缓存 key 同一时间过期,大量请求直接打到数据库,数据库直接宕机。说白了,三个问题本质都是"缓存没挡住请求,直接打到数据库把库打挂了",只是发生的场景不一样而已。6 种亲测有效的解决方案 我整理了工作这几年实际用过的 6 种方案,覆盖了三个问题的所有场景,你可以根据自己的业务情况选。1. 缓存空值/默认值 (解决穿透) 这个是最简单粗暴的方案,对付穿透贼好用。既然用户请求的 key 在数据库里不存在,那你就把这个 key 对应的空值或者默认值写到缓存里,过期时间设短一点,比如 5 分钟。这样下次再有同样的请求过来,直接从缓存里拿空值返回,就不用打数据库了。举个代码例子:defget_user_info(user_id):# 先查缓存 user=redis.get(f"user:{user_id}")ifuser:returnjson.loads(user)ifuser!="null"elseNone# 缓存没有查数据库 user=db.query("SELECT * FROM user WHERE id = %s",user_id).first()ifnotuser:# 数据库不存在,缓存空值,过期时间 5 分钟 redis.setex(f"user:{user_id}",300,"null")returnNone# 数据库存在,写缓存,过期时间 1 小时 redis.setex(f"user:{user_id}",3600,json.dumps(user))returnuser(2026 年 4 月 20 日的资料)

【Redis】缓存三兄弟:穿透 / 击穿 / 雪崩,一文搞定定义、场景与实战方案

在 Redis 面试中,缓存穿透、缓存击穿、缓存雪崩是高频必问的“缓存三兄弟”,也是后端开发中最容易踩坑的三大问题。很多人能说出概念,却分不清场景;能背出解决方案,却讲不清原理和区别。缓存穿透 缓存穿透是指大量请求查询根本不存在的数据,导致每次请求都无法命中缓存,直接穿透到数据库,最终压垮数据库的问题。一、通俗理解 就像一家奶茶店,有人一直问“有没有卖不存在的隐藏款奶茶”,店员每次都要去仓库确认,最后被这些无效请求累垮。二、专业定义 核心特征:查询的 key 在缓存和数据库中都不存在。典型场景:恶意攻击 (用大量不存在的 ID 刷接口)、业务逻辑漏洞 (参数校验不严)。风险:数据库被大量无效查询打满,影响正常业务。三、解决方案 (结合项目实战) 方案 1:缓存空值 (简单直接) 思路:对查询结果为空的 key,也在缓存中存一个空值 (或占位符),并设置短过期时间 (如 60 秒)。优点:实现简单,快速见效。缺点:会占用额外缓存空间,且空值过期后仍可能穿透。publicObjectgetData(Stringkey){Objectvalue=redisTemplate.opsForValue().get(key);if(value!=null){returnvalue;}// 缓存未命中,查数据库 Objectdata=dbMapper.queryData(key);if(data==null){// 缓存空值,设置短过期时间 redisTemplate.opsForValue().set(key,"NULL",60,TimeUnit.SECONDS);returnnull;}else{redisTemplate.opsForValue().set(key,data,30,TimeUnit.MINUTES);returndata;}}(搜索结果收录于 2026 年 3 月 10 日)

Redis 详解 (十二)------ 缓存穿透、缓存击穿、缓存雪崩

1、缓存穿透 一、概念 缓存穿透:缓存和数据库中都没有的数据,可用户还是源源不断的发起请求,导致每次请求都会到数据库,从而压垮数据库。如下图红色的流程:比如客户查询一个根本不存在的东西,首先从 Redis 中查不到,然后会去数据库中查询,数据库中也查询不到,那么就不会将数据放入到缓存中,后面如果还有类似源源不断的请求,最后都会压到数据库来处理,从而给数据库造成巨大的压力。二、解决办法 ①、业务层校验 用户发过来的请求,根据请求参数进行校验,对于明显错误的参数,直接拦截返回。比如,请求参数为主键自增 id,那么对于请求小于 0 的 id 参数,明显不符合,可以直接返回错误请求。②、不存在数据设置短过期时间 对于某个查询为空的数据,可以将这个空结果进行 Redis 缓存,但是设置很短的过期时间,比如 30s,可以根据实际业务设定。注意一定不要影响正常业务。③、布隆过滤器 关于布隆过滤器,后面会详细介绍。布隆过滤器是一种数据结构,利用极小的内存,可以判断大量的数据“一定不存在或者可能存在”。对于缓存击穿,我们可以将查询的数据条件都哈希到一个足够大的布隆过滤器中,用户发送的请求会先被布隆过滤器拦截,一定不存在的数据就直接拦截返回了,从而避免下一步对数据库的压力。2、缓存击穿 一、概念 缓存击穿:Redis 中一个热点 key 在失效的同时,大量的请求过来,从而会全部到达数据库,压垮数据库。这里要注意的是这是某一个热点 key 过期失效,和后面介绍缓存雪崩是有区别的。比如淘宝双十一,对于某个特价热门的商品信息,缓存在 Redis 中,刚好 0 点,这个商品信息在 Redis 中过期查不到了,这时候大量的用户又同时正好访问这个商品,就会造成大量的请求同时到达数据库。二、解决办法 ①、设置热点数据永不过期 对于某个需要频繁获取的信息,缓存在 Redis 中,并设置其永不过期。当然这种方式比较粗暴,对于某些业务场景是不适合的。②、定时更新 比如这个热点数据的过期时间是 1h,那么每到 59minutes 时,通过定时任务去更新这个热点 key,并重新设置其过期时间。③、互斥锁 这是解决缓存穿透比较常用的方法。互斥锁简单来说就是在 Redis 中根据 key 获得的 value 值为空时,先锁上,然后从数据库加载,加载完毕,释放锁。若其他线程也在请求该 key 时,发现获取锁失败,则睡眠一段时间 (比如 100ms) 后重试。(消息于 2026 年 4 月 21 日发布)

Redis缓存击穿实战解析,从原理到解决方案,科普缓存击穿与穿透区别

【高并发实战】Redis 缓存穿透、击穿、雪崩:3 大经典的“炸库”危机与自救指南

我们引入 Redis 的初衷,是让它作为“防弹衣”挡在 MySQL 数据库前面,拦截大部分的读取请求。但在高并发场景下,如果这层防弹衣破了 (缓存失效) 或者没防住 (查询不存在的数据),海量的流量就会瞬间打到脆弱的数据库上,导致数据库 CPU 飙升甚至宕机。这就是我们常说的缓存穿透、缓存击穿、缓存雪崩。这三个词听起来很像,但成因和解决方法完全不同。今天一文帮你彻底厘清。1. 缓存穿透 (Cache Penetration) 比喻:你的防弹衣上全是洞,子弹直接穿过去打中身体。现象:用户想要查询一个数据,Redis 里没有,数据库里也没有。结果就是:每次请求都会穿过 Redis,去查一遍数据库,然后返回空。当有恶意攻击者利用脚本疯狂查询不存在的 ID(如 id=-1) 时,数据库会被瞬间打垮。核心原因:查询了根本不存在的数据。解决方案:方案 A:缓存空值 (Cache Null Value) 当数据库没查到时,我们也往 Redis 里存一个 null 或空字符串,并设置一个较短的过期时间 (比如 30 秒)。优点:实现简单。缺点:消耗内存 (如果攻击者随机生成无数个 ID)。方案 B:布隆过滤器 (Bloom Filter) —— 推荐 在访问 Redis 之前,先加一道屏障。布隆过滤器能通过极小的内存判断“某样东西一定不存在或可能存在”。如果布隆过滤器判定 ID 不存在,直接拦截,根本不让请求碰 Redis 和数据库。2. 缓存击穿 (Cache Breakdown) 比喻:防弹衣上某一个点 (比如心脏部位) 破了个洞,狙击手盯着这个点打。现象:某一个热点 Key(比如微博热搜第一名的 ID),在不停地扛着大并发。突然,这个 Key 的过期时间到了。就在缓存失效的这一瞬间,成千上万的请求同时涌入,发现 Redis 没数据,全部冲向数据库。数据库瞬间被单一的热点数据压垮。核心原因:单一热点 Key 过期 + 高并发。解决方案:方案 A:互斥锁 (Mutex Lock) 当发现 Redis 没数据时,不要所有人一窝蜂去查数据库。大家排队,只让第一个人去查,查到了写回 Redis,后面的人直接读 Redis。代码逻辑:使用 SETNX 获取锁。方案 B:逻辑过期 (Logical Expiration) 物理上不设置过期时间 (永不过期),但在 Value 内部存一个时间戳。查询时检测到时间戳过期了,异步开启一个线程去更新数据,当前请求先返回旧数据。(撰于 2025 年 12 月 30 日)

FAQ

缓存击穿和缓存穿透的主要区别是什么?

Redis缓存击穿实战解析,从原理到解决方案,科普缓存击穿与穿透区别

缓存击穿针对的是存在的热点数据,因过期导致并发请求直击数据库;缓存穿透针对的是不存在的数据,请求直接穿透缓存和数据库。

如何解决缓存击穿问题?

常用方案包括互斥锁(只让一个线程查库重建缓存)和逻辑过期(不设物理过期,异步更新)。

Redis缓存击穿实战解析,从原理到解决方案,科普缓存击穿与穿透区别

缓存穿透的防御手段有哪些?

主要手段有缓存空值(设置短过期时间)和使用布隆过滤器拦截非法请求。