1. 缓存基础概念
1.1 什么是缓存
缓存(Cache)是一种将数据临时存储在高速存储介质中的技术,目的是在后续请求中能够更快地访问这些数据,而无需每次都从原始数据源(如数据库、磁盘文件或远程服务)重新获取。在计算机系统中,缓存无处不在:CPU 有 L1/L2/L3 缓存、操作系统有页面缓存、浏览器有 HTTP 缓存,而在微服务架构中,Redis 是最常用的分布式缓存中间件之一。
缓存的核心思想是“空间换时间”——用额外的存储空间来换取数据访问速度的提升。一个典型的缓存系统包含三个基本操作:
- 写入缓存:将数据从原始源复制到缓存中,并设置过期策略。
- 读取缓存:请求到达时优先查询缓存,命中则直接返回。
- 失效/淘汰:当缓存数据过期或缓存空间不足时,按策略移除旧数据。
1.2 缓存的作用
在微服务架构中,引入缓存层(尤其是 Redis)可以带来以下核心收益:
| 作用维度 | 具体说明 | 典型效果 |
|---|---|---|
| 降低延迟 | 内存访问延迟通常在微秒级,而数据库磁盘 I/O 在毫秒级,差距可达 1000 倍以上 | 接口响应时间从 50ms 降至 1ms |
| 减轻数据库压力 | 缓存吸收大部分读请求,数据库连接数和查询量大幅下降 | 数据库 QPS 从 10000 降至 1000 |
| 提升系统吞吐量 | 缓存层可水平扩展,支撑更高的并发请求 | 系统 TPS 从 500 提升至 5000 |
| 应对流量尖峰 | 秒杀、热点事件等突发流量由缓存层缓冲,防止后端雪崩 | 抗住 10 倍突发流量 |
| 降低运营成本 | 减少数据库扩容需求,降低 CPU/IO 资源消耗 | 数据库实例数减少 50% |
1.3 缓存穿透 / 击穿 / 雪崩
这三个问题是缓存系统中最高频的故障场景,被称为“缓存三大坑”。理解它们的定义、成因和区别,是设计高可用缓存系统的前提。
1.3.1 缓存穿透
定义:客户端请求的数据在缓存和数据库中都不存在,导致每次请求都直接穿透缓存层,打到数据库上。由于数据库中也没有该数据,每次查询都是无效查询,但数据库却要承受全部请求压力。
典型场景:恶意攻击者伪造大量不存在的用户 ID(如负数、超长 ID)发起请求;或者查询历史数据,但数据已被物理删除。
危害:数据库连接数被无效查询占满,正常业务请求无法执行,严重时可导致数据库宕机。
1.3.2 缓存击穿
定义:一个热点 key(例如秒杀商品、热搜新闻)在缓存过期失效的瞬间,大量并发请求同时发现缓存未命中,于是全部回源到数据库查询,导致数据库压力瞬间激增。
典型场景:电商大促时,某个爆款商品的详情页缓存过期,数万用户同时刷新页面,所有请求同时穿透到数据库。
危害:数据库 QPS 瞬间飙升到正常值的几十倍,可能导致数据库连接池耗尽、响应超时甚至宕机。
1.3.3 缓存雪崩
定义:缓存层中大量 key 同时过期失效,或者 Redis 服务本身发生故障(如宕机、网络分区),导致所有请求全部落到数据库上,引发数据库压力暴增甚至崩溃。
典型场景:系统上线时给所有缓存设置了相同的过期时间(如 1 小时),1 小时后所有 key 同时过期,数据库瞬间被压垮。
危害:雪崩是三大问题中危害最严重的,可能导致整个微服务系统级联故障,恢复时间也最长。
1.3.4 三大问题对比总结
| 对比维度 | 缓存穿透 | 缓存击穿 | 缓存雪崩 |
|---|---|---|---|
| 根本原因 | 数据不存在 | 热点 key 失效 | 大量 key 同时失效 / 缓存宕机 |
| 影响范围 | 单个 key 或少量 key | 单个热点 key | 大量 key 或整个缓存层 |
| 数据库压力 | 持续低效查询 | 瞬间高并发 | 持续超高并发 |
| 常用解决方案 | 布隆过滤器、空值缓存、参数校验 | 互斥锁、逻辑过期、热点 key 永不过期 | 过期时间随机化、缓存高可用(哨兵/集群)、限流降级 |
| 预防难度 | 低 | 中 | 高 |