1. 缓存穿透问题全景:定义、产生原因、业务场景与危害分析
1.1 缓存穿透的定义与核心特征
缓存穿透(Cache Penetration)是指查询一个根本不存在的数据时,由于缓存层无法命中(Cache Miss),导致请求直接穿透到后端数据库(DB)的现象。其核心特征在于:每次请求都绕过缓存,直击数据库,即使数据库中也无此记录。
关键区别:缓存穿透与缓存击穿、缓存雪崩不同。穿透针对“不存在的数据”;击穿针对“热点 key 失效”;雪崩针对“大量 key 同时失效”。
| 对比维度 | 缓存穿透 | 缓存击穿 | 缓存雪崩 |
|---|---|---|---|
| 目标数据 | 不存在的数据 | 热点 key(存在) | 大量 key(存在) |
| 失效模式 | 永远无法缓存 | 单个 key 过期 | 批量 key 同时过期 |
| 数据库压力 | 持续空查询 | 瞬时高并发 | 洪峰流量 |
| 典型应对 | 布隆过滤器 / 空值缓存 | 互斥锁 / 逻辑过期 | 过期时间打散 / 降级 |
1.2 产生原因深度剖析
缓存穿透的产生并非偶然,通常由以下三类原因叠加导致:
- 恶意攻击或爬虫扫描:攻击者构造大量不存在的 ID(如负数、超大数、随机字符串)发起请求,绕过缓存直接压向数据库。
- 业务逻辑缺陷:查询参数未做合法性校验,例如用户 ID 为 0 或负数、订单号格式错误等,导致缓存层直接回源。
- 数据冷热不均与缓存策略不当:某些数据本身就不存在(如已删除的历史记录),但业务层未做空值标记,导致每次查询都穿透。
经验法则:80% 的缓存穿透问题源于入口参数校验缺失,而非缓存中间件本身。先做参数校验,再做缓存策略。
1.3 典型业务场景
- 电商商品详情:恶意用户遍历不存在的商品 ID(如 -1、0、99999999),导致数据库频繁空查。
- 用户信息查询:批量查询已注销或未注册的用户 ID,缓存层无法命中,数据库持续返回空结果。
- 短链接服务:攻击者构造大量不存在的短码,每次请求都穿透到数据库查询映射表。
- 权限校验系统:查询不存在的 token 或 session,每次都需要回源数据库验证。
1.4 危害分析:从性能到可用性
| 危害层级 | 具体表现 | 量化指标 |
|---|---|---|
| 数据库连接耗尽 | 大量空查询占用连接池,正常业务请求无连接可用 | 连接池活跃数 100% → 请求排队超时 |
| 数据库 CPU/IO 飙升 | 无效 SQL 执行导致磁盘 IO 和 CPU 负载急剧上升 | QPS 空查占比 > 80% → 数据库响应延迟从 5ms 升至 500ms |
| 缓存层失效 | 缓存层虽然无数据,但网络开销和序列化开销依然存在 | Redis 每秒处理无效请求数激增,有效命中率下降 |
| 系统雪崩风险 | 数据库扛不住后触发熔断/降级,导致整体服务不可用 | 可用性从 99.99% 降至 90% 以下 |
1.5 缓存穿透流程示意图
1.6 穿透危害的量化案例
真实案例参考:某电商平台在促销期间遭遇恶意爬虫,每秒发起 10,000 个不存在的商品 ID 查询。缓存命中率从 95% 骤降至 20%,数据库连接池瞬间打满,正常用户请求超时率高达 60%,最终导致核心商品接口熔断 15 分钟。
从上述案例可以看出,缓存穿透的破坏力并非线性增长,而是指数级放大。一个空查询在数据库层可能仅消耗 1ms,但当并发量达到万级时,数据库的线程池、连接池、磁盘 IO 会迅速达到瓶颈,引发连锁反应。
1.7 穿透治理的总体思路
针对缓存穿透,业界已形成一套成熟的治理体系,核心思路分为三个层面:
- 事前预防:参数校验、布隆过滤器、空值缓存(缓存 null 值并设置较短 TTL)。
- 事中兜底:接口限流、熔断降级、数据库连接池参数优化(如最小空闲连接、最大等待时间)。
- 事后补偿:异步数据一致性修复、监控告警、慢查询日志分析。
课程预告:本章后续将深入讲解布隆过滤器的数学原理与工程实现、空值缓存的 TTL 策略、以及如何通过连接池参数配置来抵御穿透冲击。