ARTICLE / 3 MIN READ
高并发缓存设计的四个故障陷阱
通过缓存穿透、击穿、雪崩和热点 Key 的实战策略,建立可恢复的缓存层。
缓存能把大量读请求挡在数据库之外,但缓存本身也会故障。高并发场景下,缓存问题往往不是“读不到数据”,而是瞬间把流量推回数据库。
缓存穿透
穿透是请求查询一个业务上不存在的 ID,缓存和数据库都查不到,攻击者或错误客户端可以持续制造这类请求。
常用组合是参数校验、布隆过滤器和空值缓存。空值缓存必须设置较短 TTL,避免新数据写入后长期读到不存在。
请求 -> 参数校验 -> 布隆过滤器
-> 未命中:直接返回
-> 命中:查缓存 -> 查库 -> 回填
布隆过滤器存在误判,但不会漏掉已知存在的 Key;它适合做第一道防线,不应该被当成最终事实来源。
缓存击穿
击穿发生在一个热点 Key 过期的瞬间,大量请求同时回源。可以给热点 Key 设置互斥锁或 singleflight,只允许一个请求回源,其余请求等待短时间。
锁等待必须有上限。若数据库已经异常,不能让所有请求无限等待;超时后可以返回旧值、默认值或明确的稍后重试。
缓存雪崩
雪崩通常来自批量 Key 同时过期、缓存集群重启或网络故障。TTL 加随机抖动可以减少同一时间失效:
实际 TTL = 基础 TTL + random(0, 300 秒)
对大批量预热数据,应该分批写入并限速。发布前预热也要有容量预算,避免预热本身打满 Redis 和数据库。
热点 Key
单个 Key 被数万请求访问时,即使 Redis 总吞吐足够,也可能因为单分片、网络连接或序列化成为瓶颈。可选方案包括本地短缓存、热点副本 Key、读副本和请求合并。
本地缓存要设置极短 TTL,并通过版本号或消息通知失效;否则最容易出现跨实例的不一致。
一致性策略要先写清楚
| 业务类型 | 推荐策略 |
|---|---|
| 商品详情 | Cache-Aside,允许秒级旧值 |
| 库存余额 | 数据库扣减为准,缓存只做展示 |
| 配置开关 | 发布时版本化,主动失效 |
| 排行榜 | 定时重算或增量更新 |
写路径通常是先更新数据库,再删除缓存。若担心删除失败,可以用消息队列重试删除,并记录版本号避免旧消息覆盖新缓存。
监控不能只看命中率
还要观察回源 QPS、空值命中率、热点 Key 访问分布、缓存延迟、淘汰数量、内存碎片率、连接拒绝和集群重分片。只有把缓存当成一个需要限流和故障演练的依赖,才能真正承担高并发流量。
GITHUB DISCUSSION
评论与回复
评论保存在 GitHub Discussions,登录 GitHub 后即可参与,发布和回复都在本页完成。
评论区进入视口后自动加载。