Redis破箭式怎么用?高并发场景下怎么避免缓存击穿和雪崩,实现数据保护和性能优化?

文章导读
Redis 破箭式并非官方术语,通常指代应对缓存击穿、雪崩及穿透的高并发防御策略。在高并发场景下,避免缓存击穿可采用互斥锁或逻辑过期方案,确保热点 Key 失效时只有一个线程回源数据库;防止缓存雪崩需设置随机过期时间或将热点数据均匀分布;解决缓存穿透则推荐使用布隆过滤器或缓存空值。通过这些数据保护和性能优化手段,能有效降低数据库压力,提升系统稳定性。
📋 目录
  1. Redis 中,什么是缓存击穿、缓存穿透、缓存雪崩
  2. 【高并发实战】Redis 缓存穿透、击穿、雪崩:3 大经典的“炸库”危机与自救指南
  3. redis 击穿,穿透,雪崩以及解决方案「建议收藏」
  4. FAQ
A A

Redis 破箭式并非官方术语,通常指代应对缓存击穿、雪崩及穿透的高并发防御策略。在高并发场景下,避免缓存击穿可采用互斥锁或逻辑过期方案,确保热点 Key 失效时只有一个线程回源数据库;防止缓存雪崩需设置随机过期时间或将热点数据均匀分布;解决缓存穿透则推荐使用布隆过滤器或缓存空值。通过这些数据保护和性能优化手段,能有效降低数据库压力,提升系统稳定性。

Redis 中,什么是缓存击穿、缓存穿透、缓存雪崩

1、缓存介绍 缓存是互联网开发中必不可少的一部分,它能降低我们数据库的并发数,提高我们系统的性能,比如我们经常使用的 redis、emCached 等等,其中 redis 应该是大部分的人选,为什么?因为速度快,易上手,是很多开发者的首选,但是缓存同样存在着问题,如果使用的不恰当,也可能会造成非常严重的后果,这时候你可能就会有疑问,缓存只是存储一些数据而已,怎么会造成严重的后果呢?下面我就带大家一起来分析分析。2、什么是缓存?缓存 (cache),原始意义是指访问速度比一般随机存取存储器 (RAM) 快的一种高速存储器,通常它不像系统主存那样使用 DRAM 技术,而使用昂贵但较快速的 SRAM 技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。比如我们的 redis、他就是缓存中比较常见的一种,他的并发读写能力能达到 10w/s 左右的速度,这个速度是相当不错的,相对于传统的数据存储来说,比如数据库,快了不知道多少倍,传统的数据库 (mysql) 操作的都是磁盘,而 redis 操作的是内存 (ram),所以他们的速度肯定是没法比较的,由于传统数据库的读写较慢,所以并发较高的时候就会造成性能瓶颈问题,这也是为什么需要引入缓存的原因之一。再唠一下~ 缓存的出现,同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题无解。如果对数据的一致性要求很高,那么就不能使用缓存。另外的一些典型问题就是,缓存穿透、缓存雪崩和缓存击穿。目前,业界也都有比较流行的解决方案。本篇文章,并不是要更加完美的解决这三个问题,也不是要颠覆业界流行的解决方案。而是,从实际代码操作,来演示这三个问题现象。之所以要这么做,是因为,仅仅看这些问题的学术解释,脑袋里很难有一个很形象的概念,有了详细的描述,可以加深对这些问题的理解和认识。2、缓存击穿 缓存击穿,是指一个 key 非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问,当这个 key 在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。小编在做电商项目的时候,把这货就成为“爆款”。其实,大多数情况下这种爆款很难对数据库服务器造成压垮性的压力。达到这个级别的公司没有几家的。(撰于 2026 年 4 月 13 日)

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

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 日)

redis 击穿,穿透,雪崩以及解决方案「建议收藏」

1) 通过 synchronized+ 双重检查机制:某个 key 只让一个线程查询,阻塞其它线程 在同步块中,继续判断检查,保证不存在,才去查 DB。例如:private static volaite Object lockHelp=new Object(); public String getValue(String key){ String value=redis.get(key,String.class); if(value==”null”||value==null||StringUtils.isBlank(value){ synchronized(lockHelp){ value=redis.get(key,String.class); if(value==”null”||value==null||StringUtils.isBlank(value){ value=db.query(key); redis.set(key,value,1000); } } } return value; } 缺点:会阻塞其它线程 2) 设置 value 永不过期 这种方式可以说是最可靠的,最安全的但是占空间,内存消耗大,并且不能保持数据最新 这个需要根据具体的业务逻辑来做 个人觉得如果要保持数据最新不放这么试试,仅供参考:起个定时任务或者利用 TimerTask 做定时,每个一段时间多这些值进行数据库查询更新一次缓存,当然前提时不会给数据库造成压力过大 (这个很重要) 3) 使用互斥锁 (mutex key) 业界比较常用的做法,是使用 mutex。简单地来说,就是在缓存失效的时候 (判断拿出来的值为空),不是立即去 load db,而是先使用缓存工具的某些带成功操作返回值的操作 (比如 Redis 的 SETNX 或者 Memcache 的 ADD) 去 set 一个 mutex key,当操作返回成功时,再进行 load db 的操作并回设缓存;否则,就重试整个 get 缓存的方法。SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。在 redis2.6.1 之前版本未实现 setnx 的过期时间,所以这里给出两种版本代码参考:public String get(key) { String value = redis.get(key); if (value == null) { //代表缓存值过期 //设置 3min 的超时,防止 del 操作失败的时候,下次缓存过期一直不能 load db if (redis.setnx(key_mutex, 1, 3 * 60) == 1) { //代表设置成功 value = db.get(key); redis.set(key, value, expire_secs); redis.del(key_mutex); return value; } return value; } else { //这个时候代表同时候的其他线程已经 load db 并回设到缓存了,这时候重试获取缓存值即可 sleep(10); get(key); //重试 } } else { return value; }(发布时间是 2024 年 8 月 7 日)

FAQ

问:缓存击穿和缓存雪崩的主要区别是什么?

Redis破箭式怎么用?高并发场景下怎么避免缓存击穿和雪崩,实现数据保护和性能优化?

答:缓存击穿是指某一个热点 Key 在失效的瞬间,大量并发请求直接冲向数据库,导致数据库压力骤增;而缓存雪崩是指大量 Key 在同一时间过期,或者 Redis 服务宕机,导致大量请求同时落在数据库上,造成数据库崩溃。击穿是单点热点失效,雪崩是大面积失效。

问:如何有效解决缓存穿透问题?

答:解决缓存穿透最常用的方法是使用布隆过滤器,在访问缓存前拦截不存在的数据请求;另一种简单方法是缓存空值,当数据库查询为空时,也将空结果存入缓存并设置较短的过期时间,防止恶意攻击者频繁查询不存在的数据导致数据库压力过大。