缓存击穿与雪崩分层防御:一次促销接口被打穿的复盘
促销开始后十分钟,商品详情接口延迟从几十毫秒涨到数秒,数据库连接池打满,缓存命中率从九成以上跌到三成以下。第一反应是扩容数据库,但真正的问题不在算力,而在缓存失效的连锁反应:一个热点商品的缓存到期后,大量请求同时回源;随后更多缓存陆续到期,请求像潮水一样压到数据库上。
一、击穿与雪崩的区别
击穿是单个热点键失效,瞬间并发全部打到后端;雪崩是大量键在相近时间集中失效,整体回源量陡增。两者都会让数据库过载,但防御重点不同:击穿要挡住单点并发,雪崩要打散失效时间和回源节奏。把两者混为一谈,只加一层缓存,往往治标不治本。
二、本地缓存加分布式缓存加回源保护三层
第一层是应用本地缓存,适合读多写少、允许短暂不一致的商品基础信息,过期时间设得短一些。第二层是分布式缓存,承载跨实例共享的热点数据,键名要规范,例如 promo:sku:10086。第三层是回源保护:数据库前加单飞请求合并、异步刷新和熔断,缓存未命中时只放少量请求真正查库,其余请求等待或返回旧值。
三、热点键预热与互斥锁
促销开始前,先把确定会热的商品、价格档位和库存快照预热进缓存,避免冷启动。热点键不要用固定过期时间,改成基础时间加随机抖动,例如在 300 秒上下浮动几十秒,防止集中到期。单个热点键回源时,用互斥锁保证同一时间只有一个请求查库,其他请求等待锁释放后直接读缓存;锁必须设置超时,防止持有者异常导致后续请求全部阻塞。
四、降级与限流兜底
当回源队列已经排满时,继续放行只会拖垮所有接口。此时要按接口分级降级:先返回缓存旧值或简化版商品信息,关闭非核心的推荐、评价聚合等附加查询;同时对促销接口做限流,超出部分快速失败并给出可重试提示,而不是让请求在数据库前无限排队。降级不是放弃服务,而是保住核心链路。
五、落地检查清单
上线前逐项核对:热点键是否已预热;过期时间是否加了随机抖动;互斥锁是否有超时与释放保障;单飞合并是否只对可合并的读请求生效;降级开关是否可一键开启;缓存命中率、回源量和数据库连接数是否已接入告警。复盘后我们把这份清单写进发布检查表,促销接口的缓存命中率回到九成以上,数据库连接数也不再因为一次失效而被打满。
- 点赞
- 收藏
- 关注作者
评论(0)