一、缓存失效的本质:为什么缓存命中率会低?

大家好,我是老张。今天咱们聊聊缓存命中率偏低这个老大难问题。

说实话,我见过太多团队一上来就堆缓存,Redis 集群搞得轰轰烈烈,结果一压测,命中率不到 50%。钱花了,性能没上去,老板还觉得你技术不行。

缓存命中率低,说白了就是缓存没起到应有的作用。那问题出在哪?我习惯从三个维度去剖析:缓存穿透、缓存击穿、缓存雪崩。这三个词大家肯定不陌生,但真正理解它们本质的人,其实不多。

核心观点:缓存命中率低,不是缓存本身的问题,而是缓存策略与业务场景不匹配的问题。

缓存命中率低三大根因 缓存命中率低 根源分析 缓存穿透 查不存在的数据 绕过缓存直击DB 缓存击穿 热点key过期 高并发打穿 缓存雪崩 大面积key同时过期 DB瞬间被打爆 三者本质不同,但都会导致缓存命中率断崖式下跌

1.1 缓存穿透:查了个不存在的东西

先讲缓存穿透。这词听起来挺玄乎,其实说白了就是——客户端查了一个缓存和数据库里都不存在的数据。

举个例子。你有个用户信息缓存,key 是 userId。正常情况下,查 userId=1001,缓存有就返回,没有就去 DB 查,然后回填缓存。但要是有人恶意传个 userId=-1 呢?缓存里没有,DB 里也没有。每次请求都直接打到数据库上。

我在项目中遇到过类似情况。有一次线上告警,数据库连接数飙到 2000+。查了半天,发现是某个爬虫在遍历不存在的商品 ID。那叫一个酸爽。

避坑指南:我曾经以为布隆过滤器能解决一切穿透问题,后来发现它只能判断"一定不存在",不能判断"一定存在"。所以布隆过滤器适合拦截恶意请求,但正常业务还得靠其他手段兜底。

缓存穿透的本质是什么?我总结了两点:

  • 数据不存在:业务上确实没有这条数据,但请求量很大
  • 缓存策略缺失:没有对"查不到"的情况做特殊处理

你想想看,如果每次穿透都去查 DB,那缓存还有什么意义?

1.2 缓存击穿:热点 key 突然挂了

缓存击穿,这个更常见。它指的是某个热点 key 在过期瞬间,大量并发请求同时打到数据库。

注意关键词:热点 key。不是所有 key 过期都会造成击穿,只有那些被高并发访问的 key 才会。

我记得有个社交 App 的首页 Feed 流,缓存 key 设置过期时间 1 小时。结果每到整点,数据库就抖一下。为什么?因为整点一到,所有用户的首页缓存同时过期,几千个请求同时去 DB 拉数据。

场景 正常情况 击穿情况
请求数量 1000 QPS 1000 QPS
缓存命中 990 次命中 0 次命中(key 刚过期)
DB 压力 10 QPS 1000 QPS
结果 正常 DB 打满,接口超时

看到没?命中率从 99% 瞬间掉到 0%。这就是击穿的威力。

注意:缓存击穿和缓存穿透的区别在于——击穿是"曾经有,刚过期";穿透是"从来就没有"。处理方式完全不同。

1.3 缓存雪崩:大面积 key 集体阵亡

缓存雪崩,是击穿的升级版。它指的是大量 key 在同一时间过期,导致 DB 瞬间被海量请求淹没。

为什么会这样?我见过最典型的场景:

  • 所有缓存 key 设置了相同的过期时间(比如凌晨 0 点过期)
  • Redis 实例宕机,整个缓存层失效
  • 缓存预热时,大量 key 同时写入又同时过期

嗯,这里要注意。雪崩和击穿最大的区别是范围。击穿是单个 key 的事故,雪崩是整个缓存层的灾难。

我在一家电商公司遇到过真实案例。双十一大促,运营把所有商品缓存过期时间设成了 00:00:00。结果 0 点一过,数据库直接被打挂了。那晚我们紧急扩容了 3 次才稳住。

核心区别总结:

  • 穿透:查不存在的数据 → 布隆过滤器 + 空值缓存
  • 击穿:热点 key 过期 → 互斥锁 + 逻辑过期
  • 雪崩:大面积 key 过期 → 过期时间加随机值 + 多级缓存

1.4 三个维度的本质剖析

讲到这里,我想把这三个问题的本质再捋一捋。

缓存穿透的本质:缓存层和存储层之间的数据不一致。缓存认为"没有",DB 也认为"没有",但请求还在源源不断地来。说白了,就是缓存没有能力拦截"不存在"的请求。

缓存击穿的本质:热点数据的保护机制缺失。单个 key 过期不可怕,可怕的是过期瞬间的高并发。这就像红绿灯坏了,十字路口的车全挤在一起。

缓存雪崩的本质:缓存层的整体可用性被破坏。要么是设计上的"集体过期",要么是基础设施的"集体宕机"。不管哪种,结果都是缓存层形同虚设。

我个人习惯把这三个问题画成一个三角:

缓存命中率低
    ├── 穿透:数据不存在 → 缓存形同虚设
    ├── 击穿:热点过期 → 缓存瞬间失效
    └── 雪崩:大面积失效 → 缓存层崩塌

你发现没有?这三个问题虽然表现不同,但根因都指向同一个方向——缓存策略没有考虑到边界情况。

我的经验:解决缓存命中率问题,不要一上来就调参数、换中间件。先搞清楚你的业务场景属于哪种"失效模式",然后对症下药。我曾经见过有人用分布式锁解决穿透问题,结果锁的开销比查 DB 还大,得不偿失。

好了,这一章我们搞清楚了缓存命中率低的三个根本原因。下一章我会详细讲怎么针对每种情况做优化。记住一句话:缓存不是银弹,用不好就是炸弹。


想要更多资料,联系可可