Appearance
缓存穿透治理怎么做更稳
缓存穿透最容易被轻描淡写地总结成一句话:
“查不到的数据也缓存一下就行。”
这只能解决最浅的一层。真正线上遇到的穿透问题,往往来自下面几类情况:
- 大量恶意或异常参数直接打到 DB
- 业务 ID 本身就是稀疏的,空值数量巨大
- 热点接口在缓存 miss 时回源风暴叠加
- 某些不存在对象根本不应该进入数据库层
先说结论
- 缓存穿透是“不存在的数据反复绕过缓存打到下游”,核心目标是让无效请求尽早被挡住
- 空值缓存、布隆过滤器、参数校验、限流降级往往要组合使用
- 不要把穿透、击穿、雪崩混成一个问题,它们的治理手段侧重点不同
- 真正稳的治理策略,一定包含监控和降级,不只是一个缓存技巧
先把问题定义清楚
缓存穿透指的是:
- 请求访问的数据在缓存里没有
- 在数据库里也没有
- 每次请求都会直接打穿到数据库
它和另外两个常见问题要分开看:
- 缓存击穿: 热点 key 失效,瞬时大量请求回源
- 缓存雪崩: 大量 key 同时失效或缓存整体不可用
穿透的关键词是“不存在的数据”。
为什么它危险
因为它天然绕开了缓存系统的保护能力。
如果有人持续用不存在的用户 ID、订单号、商品 ID 打接口,请求会稳定命中数据库。
一旦并发大起来,风险会表现为:
- DB QPS 异常上涨
- 慢 SQL 和连接数上升
- 缓存命中率看似正常,但接口 RT 明显抖动
- 业务层线程池开始排队
第一层治理: 参数前置校验
这是最容易被忽略、但性价比最高的一层。
例如:
- 用户 ID 必须为正整数
- 订单号必须满足固定长度和前缀规则
- 枚举类参数必须在白名单内
如果参数本身就非法,就不该放进缓存和数据库层。
这一层的特点是:
- 成本低
- 延迟低
- 能挡住大量明显异常流量
第二层治理: 空值缓存
当请求的数据确实合法,但数据库里不存在时,可以把“空结果”也短暂缓存起来。
例如:
text
key = user:123456789
value = NULL_PLACEHOLDER
ttl = 60s这样后续相同请求在一段时间内就不会再打数据库。
空值缓存的优点
- 简单直接
- 对单个不存在对象的反复查询很有效
它的边界
- 如果恶意请求 ID 非常离散,空值 key 会迅速膨胀
- TTL 不能太长,否则真实数据刚创建后可能还会被旧空值挡住
所以空值缓存适合:
- 非法请求不离散
- 不存在对象重复访问概率高
第三层治理: 布隆过滤器
布隆过滤器适合“先判断这个对象大概率是否存在”。
它特别适合:
- 用户 ID、商品 ID、配置 ID 这类可预先加载的主键集合
- 数据量大,但希望在进入缓存前先挡掉明显不存在的请求
典型流程是:
- 先查布隆过滤器
- 如果明确不存在,直接返回
- 如果可能存在,再查缓存和数据库
它的优点
- 内存占用小
- 对大规模稀疏 ID 很有效
它的限制
- 有误判率,只能说“可能存在”
- 数据更新时要考虑同步问题
- 不适合频繁删除且要求绝对准确的集合
第四层治理: 限流和降级
如果穿透流量已经演化成攻击或系统异常,仅靠缓存技巧不够。
必须配合接入层和业务层的保护机制:
- 网关限流
- IP / 用户维度封禁
- 接口级熔断降级
- 异常参数快速失败
一个常见误区是把穿透完全交给 Redis 处理。
实际上真正的第一道防线往往在 API 网关和业务网关。
一个更稳的组合方案
大多数业务系统可以按这个顺序落地:
- 参数合法性校验
- 热门对象走本地缓存 + Redis
- 不存在对象短 TTL 空值缓存
- 主键集合大的场景补布隆过滤器
- 网关和服务层加限流熔断
这套组合通常比“只上一个 BloomFilter”更稳,也更容易维护。
工程上要特别注意的坑
1. 空值 TTL 过长
真实数据刚创建时,用户仍然可能读到“空结果”,造成短暂不一致。
2. 布隆过滤器和真实数据不同步
如果布隆集合没及时更新,会把合法请求提前挡掉。
3. 只看缓存命中率,不看无效请求比例
缓存命中率高,不代表没有穿透。
你还要关注:
- miss 中数据库未命中的比例
- 某类接口 404 / 空结果比例
- 参数异常率
4. 把穿透问题拖成 DB 问题才处理
很多团队直到数据库连接数打满才反应过来,实际上网关层早该挡掉了。
一个排查思路
当怀疑线上有缓存穿透时,可以顺着这条线查:
- 某接口 miss 率是否异常升高
- miss 后 DB 未命中比例是否很高
- 是否集中在某类非法或稀疏 ID
- 请求来源是否集中在某 IP、某用户、某渠道
- 当前是否已有空值缓存或布隆过滤器
这样才能区分到底是:
- 正常业务流量结构变化
- 上游参数异常
- 恶意攻击
总结
缓存穿透治理的重点不是“记住几个术语”,而是把无效请求尽量拦在系统前面。
真正稳的方案通常不是单点技巧,而是:
- 参数校验
- 空值缓存
- 布隆过滤器
- 限流降级
- 监控告警
这五层一起做,系统抗穿透能力才会真正上一个台阶。