跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Redis集群下防止缓存击穿_如何精准定位热点Key并加锁

真正要加锁的热点Key是QPS突增、缓存命中率断崖下跌、过期时间集中的少数几十个key;可通过业务层日志告警(空返回且距过期≤200ms)和实时TTL验证精准定位。 怎么识别出真正要加锁的 热点 Key 别一上来就给所有
product:10086
这类 key 加锁,Redis 集群里 99% 的 key 根本不值得锁。真正在击穿时造成 DB 压垮的,往往只有几十个——它们有共同特征:QPS 突增 + 缓存命中率断崖下跌 + 过期时间集中。用
redis-cli --stat
只能看到总量,得结合监控打点才准。 推荐两个低成本定位方式: 在业务层
cache.Get()
后加一行日志:当返回空且当前时间距 key 设置的过期时间 key 和
ts
用 Redis 自带的
MEMORY USAGE
+
OBJECT IDLETIME
组合查:对命中率低但内存占用高的 key,再查它最近 5 分钟的
INFO commandstats
中
cmdstat_get
调用量突增情况 注意:不要依赖
KEYS *
扫全量,集群下会阻塞;也别信“访问量 Top 100”这种静态排名,突发热点(如热搜商品)根本不在里面。 SETNX 锁在 Redis 集群里为什么容易失效 直接用
SETNX lock:product:10086 1 EX 10
在集群模式下可能锁不住——因为 key
lock:product:10086
和数据 key
product:10086
可能落在不同 slot,而 SETNX 不保证原子跨 slot。结果就是:锁设在 slot 2,但数据在 slot 8,别的客户端照样能绕过去读 DB。 必须让锁 key 和数据 key 落在同一个 slot: 强制哈希标签:把锁 key 写成
lock:{product:10086}
,大括号内内容参与 CRC16 计算,确保和
product:10086
同 slot 避免用随机字符串做锁 value,要用可识别来源的标识(如
service-a:pid-12345
),方便排查谁没释放 超时时间别硬写 10 秒,得略大于你 DB 查询 +
SET
缓存的 P99 耗时,建议先压测再定 加锁后返回旧值还是等新值,怎么选 这不是纯技术问题,是业务容忍度问题。秒杀商品详情页可以返回逻辑过期的旧值(比如库存显示“99”,实际已售完),但价格页绝对不行。 Redis 8.2.3 Redis 8.2.3 是一款安全优先的高性能键值存储系统。该版本紧急修复了可能引发远程代码执行(RCE)的高危漏洞(CVE-2025-62507),并解决了 HyperLogLog 及 Cuckoo Filter 等数据结构在特定场景下的崩溃问题。建议所有用户立即升级,以保障生产环境的系统稳定与数据安全。 下载 两种策略的实际取舍点: 返回旧值:需确保旧值本身没被其他线程误删(比如后台任务清缓存时没判断锁状态),且旧值过期时间字段得存在并可读(推荐把过期时间存进 value JSON 里,如
{"data":{...},"expire_at":1743870222}
) 等待新值:客户端最多等 300ms,超时直接降级(如返回兜底文案或空结构),别无限制重试——否则线程池会积压,变成雪崩前兆 最危险的是“半等半返回”:部分请求等、部分不等,导致前端渲染不一致,用户刷一次一个样。 预热失败时,为什么监控比加锁还重要 主动预热
product:10086
是防击穿的上策,但如果你的预热 SQL 没走索引,或者预热脚本连错从库,那它不仅没防住击穿,反而先把自己搞挂了。 必须盯死三项指标: 预热任务的执行耗时是否稳定(波动 > 200ms 就要告警) 预热后该 key 的
TTL
是否真的被重置(用
TTL product:10086
实时验证) 预热期间 DB 的慢查询日志里,有没有对应
SELECT ... WHERE id = 10086
出现 很多团队卡在这儿:预热脚本每天跑,但从没人看日志,直到某天缓存集体过期,才发现半年前预热就静默失败了。

相关文章