redis缓存:雪崩、穿透、击穿详解

一、缓存三兄弟

1. 缓存雪崩(Cache Avalanche)

问题描述:

大量的缓存数据在同一时间集中失效,此时请求全部打到MySQL,造成MySQL崩溃或响应能力降低。

场景还原:

  • Redis最初是空的,需要预热
  • 大量缓存数据设置了相同的过期时间
  • Redis重启或MySQL/存储系统重启后,缓存空窗期请求全打MySQL

解决方案:

方案 说明
间隔设置过期时间 给缓存的过期时间加上随机偏移量,避免同一时间批量失效
数据预热 系统启动或重启后,提前将热点数据加载到Redis
持久化 开启Redis持久化,避免重启后缓存全空
多级缓存 引入本地缓存作为缓冲层

2. 缓存穿透(Cache Penetration)

问题描述:

查询的数据在缓存和MySQL中都不存在,请求穿透缓存直接打MySQL,如果大量恶意请求,可能导致MySQL崩溃。

场景还原:

  • 查询一个根本不存在的key
  • 恶意请求大量不存在的数据
  • MySQL成为最后一道防线,不断被无效查询击穿

解决方案:

方案 说明
缓存空值 对不存在的数据在Redis中缓存一个空值(nil标记),下次查询直接返回
布隆过滤器(Bloom Filter) 概率型数据结构,判断某个key一定不存在,存在则可能误判

布隆过滤器部署位置对比:

部署位置 优点 缺点
部署在Server端 轻量级实现 多个Server端需要初始化多个布隆过滤器,运维压力大
部署在Redis 共享一份布隆过滤器,多个Server共用 需要额外的Redis插件支持

3. 缓存击穿(Cache Breakout)

问题描述:

某个热点key在Redis中没有数据,但MySQL中有数据。大量的并发请求同时访问Redis发现没有该数据,转而全部去请求MySQL,造成MySQL崩溃。

场景还原:

  • 热点key刚好过期
  • 大量并发请求同时发现Redis没数据
  • 所有请求同时打向MySQL

解决方案:

方案 说明
分布式锁 确保只有一个请求去查MySQL,其他请求等待结果
过热数据永不过期 对极热点数据设置永不过期或后台异步续期

二、缓存架构设计

1. 整体架构

复制代码
                    +-------+
                    | Client |
                    +---+---+
                        |
                        v
+----------------+   +-------+   +------------+   +-------+
|   Write Path   |->| Redis |   | Read Path  |<---| MySQL |
+----------------+   +-------+   +------------+   +-------+
      |                              ^
      |                              |
      v                              |
+----------------+                   |
|    MySQL       |-------------------+
+----------------+

  同步中间件(伪装成MySQL从库)

2. 读写策略

读策略流程:

复制代码
Client -> Redis存在? -> Yes -> 直接返回数据
              |
              No
              v
         查MySQL -> 有数据 -> 写入Redis -> 返回数据
                   |
                   No
                   v
              返回空/错误

写策略流程:

复制代码
Client -> 写Redis(设置过期时间) -> 写MySQL
              |
              v (等待MySQL同步到Redis)
         过期时间 = Server到MySQL同步时间 + 中间件拉取数据时间 + 传输时间
              |
              v (通常设定200ms经验值)

3. 同步中间件

核心职责:

  • 伪装成MySQL从数据库
  • 同时连接MySQL和Redis
  • 拉取MySQL的binlog变更
  • 将热点数据同步给Redis

三、缓存一致性问题

脏数据问题

场景:

写Redis成功,但写MySQL失败,此时会有约200ms的脏数据时间窗口。

时间线:

复制代码
T=0ms   Client写Redis成功
T=50ms  Client开始写MySQL
T=200ms 中间件同步MySQL到Redis
        |
        v (中间T=0ms~T=200ms是脏数据窗口)

数据一致性保证

策略 说明
先写Redis再写MySQL 保证最终一致性,有短暂脏数据窗口
过期时间兜底 即使同步失败,脏数据也会在过期后自动清除
延迟双删 写完MySQL后删除Redis,再延迟一段时间后删除

四、安全性问题汇总

问题 原因 解决方案
写Redis成功写MySQL失败 网络抖动/MySQL响应慢 过期时间兜底+告警机制
Redis数据丢失 Redis重启/故障 开启持久化(RDB/AOF)
缓存雪崩 大量key同时过期 随机过期时间+数据预热
缓存穿透 查询不存在的数据 空值缓存+布隆过滤器
缓存击穿 热点key过期+并发 分布式锁+永不过期

根据零声教育教学写作https://github.com/0voice

相关推荐
贝猫说python13 小时前
大模型比赛2.3智能体开发(工具调用智能问答助手)
数据库·oracle
许彰午15 小时前
28-ORA-01110数据文件读取错误
数据库·oracle
凯凯姜15 小时前
MySQL 联合索引设计与索引失效
数据库·mysql
猫咪很可爱15 小时前
Oracle TEMP 表空间不足(ORA-01652)问题分析与优化实践
数据库·oracle
九零HTTP16 小时前
10月21号-CSDN配菜-IP池的5个坑
服务器·数据库·tcp/ip
SHENGWEI胜为17 小时前
交换机端口显示正常,终端却获取不到 IP 地址?从 DHCP 流程定位故障
服务器·网络·测试工具·缓存·通信工程
Data-Miner17 小时前
需要做财务数据分析,有什么好用的工具?从准备到出报告的实操指南
大数据·数据库·数据分析
袋鼠云数栈17 小时前
让 SQL 解析不再重复造轮子:SqlParserX 正式开源
数据库·人工智能·sql·开源·数据治理
这个DBA有点耶18 小时前
期货 CTP 系统 Oracle RAC 迁移国产库实战:读写分离架构设计与性能对标
数据库·架构·dba
数据库安全18 小时前
AI数据访问安全 |如何控制AI访问权限,防止越权
数据库·安全