华为云 DCS for Redis 缓存治理实战:分布式锁、穿透防护与雪崩兜底

举报
yd_253000176 发表于 2026/10/27 10:34:48 2026/10/27
【摘要】 以一个商品详情查询服务为例,走通华为云 DCS for Redis 的连接选型、缓存穿透与击穿防护、SET NX PX 分布式锁续期、随机 TTL 防雪崩的完整链路,附五段可直接复用的 Python 代码与三处真实踩坑。

背景:一次商品详情页的读放大

双十一预热时我们的商品详情接口 QPS 冲到 3000,后端 RDS for MySQL 只有 4C8G,CPU 连续二十分钟顶在 95%,P99 从 80ms 涨到 1.2 秒。排查发现 SQL 并不慢,问题在于热点商品的读请求几乎完全重复,却每次都要走完整个链路。于是我们引入华为云 DCS for Redis 做缓存优先改造,改造后数据库读 QPS 下降约八成,P99 回落到 60ms 以内。下面记录落地过程。重点讲三个必须自己写代码解决的问题:穿透、击穿和雪崩。

第一步:实例与连接

在 DCS 控制台创建 Redis 5.0 主备实例,部署在与 ECS 相同的 VPC,关闭公网访问,只把业务子网加入白名单。客户端用 redis-py,关键是连接池与超时预算:socket_timeout 必须小于接口的整体超时,否则缓存抖动会连带拖垮整个请求。

pool = redis.ConnectionPool(host=ADDR, port=6379, password=PWD,
max_connections=50, socket_timeout=0.3, socket_connect_timeout=0.3)

第二步:穿透的空值兜底

穿透指查询一个根本不存在的 id,缓存永不命中,每次都落到数据库,被扫 id 时数据库会直接被压死。我们做三层防护:参数合法性校验、空值短缓存、外层布隆过滤器。命中空结果时写入六十秒的空标记,避免同一无效 id 反复回源;但 TTL 不能太长,否则商品新上架后会有最长一分钟的查不到窗口。无效 id 反复回源,等于让数据库白承担一堆无效查询。

第三步:击穿的分布式锁

击穿发生在热点 key 刚过期的一瞬间,成百请求同时未命中、一起回源。我们用 SET NX PX 做互斥重建,只让一个请求查库,其余请求短暂等待后重读缓存。释放锁必须用 Lua 脚本比对 token,不能直接 DEL。

第四步:雪崩的随机 TTL

雪崩是大量 key 在同一时刻集中过期。所有写入点统一加抖动,把 TTL 打散到基础值的百分之九十到一百一十,并在凌晨低峰预热 TOP 5000 商品。降级开关也提前准备好:Redis 异常时直接读库。同时用本地缓存限流,避免把数据库一次性压垮。

三处真实踩坑

第一,初始版本没设 socket_timeout,主备切换那半分钟里所有工作线程阻塞在建连上,接口全面超时,比没有缓存更糟。第二,锁 TTL 设成三秒而一次慢查询要八秒,锁提前释放导致并发重建,改到十秒并补索引后才稳定。第三,曾把一个十兆的评论列表塞进单个 key,传输时阻塞同一连接上的其他请求,拆成分页 key 才解决。键名也要提前规范成 业务:实体:id,否则多团队共用一个实例必然冲突。

结论

Redis 不是加了就快的银弹,真正决定稳定性的是超时预算、降级路径、key 规范和锁语义。把穿透、击穿、雪崩当成三个独立的工程问题逐个解决,缓存才会成为数据库前面的一道缓冲,而不是新的故障点。这也是我们复盘后形成的团队共识。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。