1. 缓存穿透问题概述
1.1 定义
缓存穿透(Cache Penetration)是指客户端请求的数据在缓存层和数据库层中均不存在,导致每次请求都必须穿透缓存层,直接访问后端数据库。由于缓存无法命中,所有请求压力全部落在数据库上,形成“穿透”效应。
核心特征:缓存不命中 + 数据库无记录 = 每次请求都直达数据库。
1.2 产生原因
缓存穿透的根源可归纳为以下三类场景:
| 原因分类 | 具体描述 | 典型示例 |
|---|---|---|
| 业务数据缺失 | 查询的主键或索引在数据库中本身不存在,缓存自然无法构建 | 查询一个已删除的商品ID |
| 恶意攻击/爬虫 | 攻击者构造大量不存在的Key进行高频请求,绕过缓存直接打库 | 遍历不存在的用户ID(如 -1、0、9999999) |
| 缓存预热不完整 | 系统上线或缓存过期后,部分冷数据未被加载,导致首次请求穿透 | 新上线的活动商品未提前写入缓存 |
1.3 对系统的影响
缓存穿透对系统造成的损害是连锁式的,主要体现在以下两个维度:
- 数据库压力陡增:正常情况下,缓存层拦截 90% 以上的读请求。穿透发生时,所有无效请求直接打到数据库,数据库连接池迅速耗尽,CPU 和 IO 飙升,严重时导致数据库崩溃。
- 响应延迟恶化:数据库查询耗时通常是缓存查询的 10~100 倍(缓存约 1~5ms,数据库约 10~100ms)。大量穿透请求导致平均响应时间从毫秒级恶化到秒级,甚至触发上游服务超时重试,形成雪崩效应。
风险量化:假设缓存 QPS 为 10,000,其中 1% 为穿透请求(100 QPS)。若数据库单次查询耗时 50ms,则数据库额外承受 100 QPS × 50ms = 5,000ms/s 的负载,相当于多消耗 5 个数据库连接线程。若攻击流量放大至 10%,数据库将直接过载。
1.4 穿透流程示意图
下图展示了正常请求与穿透请求的路径差异:
1.5 穿透与相关概念辨析
为避免概念混淆,下表区分了缓存穿透与另外两种常见缓存异常:
| 异常类型 | 触发条件 | 影响范围 | 典型后果 |
|---|---|---|---|
| 缓存穿透 | 数据不存在,缓存永远无法命中 | 单个无效Key | 数据库直接承受无效查询压力 |
| 缓存击穿 | 热点Key过期,大量并发请求同时穿透 | 单个热点Key | 数据库瞬间被高并发打垮 |
| 缓存雪崩 | 大量Key同时过期或缓存节点宕机 | 大面积Key失效 | 数据库被海量请求压垮,系统级故障 |