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

简介: 本文详解缓存穿透、击穿、雪崩三大问题:穿透是查不存在的数据,击穿是热点Key失效被高并发冲击,雪崩是大量Key同时过期或Redis故障。结合比喻与解决方案,助你彻底理解并防范数据库风险。

前言

我们引入 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 内部存一个时间戳。查询时检测到时间戳过期了,异步开启一个线程去更新数据,当前请求先返回旧数据。

3. 缓存雪崩 (Cache Avalanche)

比喻: 雪崩发生了,整片山坡的雪同时塌下来。

  • 现象:
    Redis 中大量的 Key 在同一时刻集体过期。
    或者,Redis 节点直接宕机了。
    结果是:原本被 Redis 拦截的海量请求,瞬间全部转移到数据库,导致数据库像被雪崩淹没一样挂掉。
  • 核心原因: 大量 Key 同时过期Redis 故障
  • 解决方案:
  • 方案 A:随机过期时间 (Random TTL)在设置过期时间时,不要都设为 1小时。而是在 1小时的基础上,加上一个随机数(比如 1-10 分钟)。这样 Key 就会分散过期,不会扎堆。
  • 公式: Expire_Time = Base_Time + Random(Value)
  • 方案 B:高可用架构
    部署 Redis 哨兵(Sentinel)或 集群(Cluster),防止单点故障导致全盘皆输。
  • 方案 C:限流与降级
    在网关层做限流,或者当数据库压力过大时,直接开启降级模式(返回默认值或“系统繁忙”),保住数据库一命。

总结:一张表看懂区别

问题 关键特征 根本原因 核心解决方案
缓存穿透 不存在的数据 数据源和缓存都没有 布隆过滤器、缓存空对象
缓存击穿 单个热点 Key 失效 局部并发过大 互斥锁、逻辑过期
缓存雪崩 大量 Key 同时失效 整体并发压力转移 随机过期时间、Redis高可用

口诀记忆:

  • 穿透:查无此人。
  • 击穿:盯着一点打。
  • 雪崩:全线崩盘。
相关文章
|
SQL Kubernetes 关系型数据库
如何一键安装部署PolarDB-X
《PolarDB-X 动手实践》系列第一期,体验如何一键安装部署PolarDB-X。
|
关系型数据库 分布式数据库 数据库
PolarDB 入门
PolarDB 入门
395 0
|
存储 JSON 关系型数据库
基于GeoTools的GeoJson导入到PostGis实战
GeoJson是一种对各种地理数据结构进行编码的格式,基于json的地理空间信息数据交换格式。GeoJson对象可以用来表示几何,特征或者特征集合。支持地理点、线、面、多点、多线、多面及几何集合。GeoJson不是本文的重点,因此不再赘述。
2346 0
基于GeoTools的GeoJson导入到PostGis实战
|
Java 数据库
【数据库】starrocks 安装踩坑
【数据库】starrocks 安装踩坑
1157 0
|
Linux iOS开发 Docker
|
关系型数据库 分布式数据库 PolarDB
PolarDB产品使用问题之如何基于Docker进行PolarDB-X单机模拟部署
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。
PolarDB产品使用问题之如何基于Docker进行PolarDB-X单机模拟部署
|
运维 监控 测试技术
如何确保微服务架构的高可用性?
如何确保微服务架构的高可用性?
492 57
Echarts各类图表常用配置项说明,附示例代码
Echarts各类图表常用配置项说明,附示例代码
|
缓存 NoSQL Java
【Redis】5、Redis 的分布式锁、Lua 脚本保证 Redis 命令的原子性
【Redis】5、Redis 的分布式锁、Lua 脚本保证 Redis 命令的原子性
946 0