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 后即可参与,发布和回复都在本页完成。

评论区进入视口后自动加载。