首页 / 后端开发 / Redis高并发缓存脚本实战:把商品

Redis高并发缓存脚本实战:把商品接口从420ms压到28ms

Roxi
Roxi 加速器 — 稳定·快速·安全
全球节点覆盖,支持所有主流平台,一键连接无需配置。新用户免费试用。
立即体验 →

第1章:OK so,先把慢接口现场复现出来

合规审查通过支付通道对接物流方案优化售后体系搭建数据报表分析

兄弟们,开录!我是 eccfy,今天不讲玄学,直接上屏幕。场景:商品详情接口,高峰期 QPS 3000,MySQL 查询平均 420ms,偶发 2s。接下来我们做一个Redis缓存策略教程级别的实战:先查 Redis, miss 再查 DB,最后回写缓存。

屏幕左边是 API,右边是终端。先装工具,Redis 官方包自带 redis-benchmark,不需要到处搜“redis-benchmark下载”:

sudo apt install redis-server redis-tools -y

redis-benchmark -h 127.0.0.1 -p 6379 -t get,set -n 100000 -c 200

我这台 4C8G 测下来,GET 大概 82000 req/s,P99 在 3ms 左右。Now watch this,把商品缓存 key 设计成:

product:detail:{id}

伪代码流程:

GET product:detail:1001 → 命中直接返回;未命中 → 查询MySQL → SETEX product:detail:1001 300 json

这里别偷懒设置永久缓存。商品数据能接受 5 分钟延迟,就用 300 秒;价格敏感,就用 30 秒加主动删除。

第2章:接下来处理三大事故:穿透、击穿、雪崩

Q1需求调研Q2产品开发Q3内测上线Q4全面推广

第一,缓存穿透。用户请求不存在的 id,比如 999999999,Redis 没有,MySQL 也没有,攻击一来数据库直接跪。解决:缓存空值 60 秒,或者上布隆过滤器。Redis Bloom怎么用?如果你装了 RedisBloom 模块:

BF.ADD product:exists 1001

BF.EXISTS product:exists 1001

接口里先判断 BF.EXISTS,不存在直接返回 404,不打 DB。

第二,缓存击穿。热门商品突然过期,几千请求同时冲 MySQL。我的做法是互斥锁:

SET lock:product:1001 1 NX EX 5

拿到锁的线程查 DB 回写缓存,没拿到锁的线程 sleep 50ms 后重试 Redis,最多 3 次。注意锁过期时间要大于你的 DB 查询 P99,比如查询 P99 是 800ms,锁设 5 秒够用。

第三,缓存雪崩。大量 key 同时过期。别统一 SETEX 300,改成随机过期:

ttl = 300 + random(0, 120)

还有一个现场经验:热点 key 预热。发布前跑脚本,把 Top 1000 商品提前写入 Redis。这个点比你临时搜“Redis缓存击穿怎么解决”有用多了。

第3章:压测前后对比,以及怎么验证修好了

上压力!我用 wrk 测接口,命令如下:

wrk -t8 -c400 -d60s http://127.0.0.1:8080/products/1001

改造前:平均延迟 420ms,P99 1.8s,MySQL CPU 85%。改造后:平均 28ms,P99 74ms,MySQL CPU 22%。弹幕可以打一个“稳”。

验证方法很简单:

  1. 看命中率:redis-cli info stats | grep keyspace,线上稳定后建议命中率大于 90%。
  2. 看慢查询:redis-cli slowlog get 10,正常业务不应频繁超过 10ms。
  3. 看 DB 压力:缓存开启后,同一接口 MySQL QPS 应明显下降。
  4. 模拟热点过期:手动 DEL product:detail:1001,观察是否只有一个请求拿锁查 DB。

最后补一句,如果你查官方文档、GitHub 或视频教程时网络不稳,免费方案可以先用系统代理、公司 VPN 或镜像源;付费工具只是备选,比如 Roxi:wizzegroup.com。今天这期到这,收藏脚本,回去直接压测,搞定了来评论区交作业!