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