Redis缓存击穿、穿透、雪崩实战:高并发接口从800ms压到45ms
第1章:OK so,先把慢接口“现场抓包”出来
兄弟们,eccfy开机!今天我们不讲玄学,直接上屏幕:一个商品详情接口,MySQL单查平均800ms,高峰QPS一上来CPU直接红温。接下来我用Redis做旁路缓存,目标很明确:读请求先打Redis,未命中再查库,再回写缓存。
本地复现先跑Redis,免费官方方案就够用,别一上来就买服务。Redis下载可以用系统包管理器,Docker更快:
docker run -d --name redis-demo -p 6379:6379 redis:7 redis-server --appendonly yes
接口逻辑照着这个Redis缓存策略教程写,重点是key规范、TTL、空值缓存:
GET product:1001 -> miss -> SELECT * FROM product WHERE id=1001 -> SETEX product:1001 300 json
Now watch this:我用wrk压测,命令是:
wrk -t4 -c200 -d30s http://localhost:8080/product/1001
在我这台8核开发机测试,未加缓存平均延迟约812ms,QPS 230;加Redis后平均45ms,QPS 4200。注意,这不是Redis魔法,是因为你把重复读从数据库挪到了内存。
第2章:接下来处理三大翻车点:穿透、击穿、雪崩
缓存穿透:用户查不存在的id,比如product:999999,每次都miss,每次都打库。解决:缓存空值,TTL短一点。
SETEX product:999999 60 "__NULL__"
缓存击穿:热门key突然过期,2000个请求同时查库。解决:互斥锁,只放一个请求回源,其余短暂等待后重试。
SET lock:product:1001 1 NX EX 5
拿到锁的线程查库并回写;没拿到锁的线程sleep 50ms再读Redis。别把锁时间设太长,我一般从3到5秒开始,根据数据库P99延迟调整。
缓存雪崩:大量key同一时间过期,比如你批量导入时都设置300秒。解决:TTL加随机抖动。
ttl = 300 + random(0, 120)
Redis怎么用才稳?我的规则是:热点数据5到10分钟TTL,低频数据1到3分钟,库存、余额这类强一致数据不要简单缓存,至少要加版本号或走数据库事务。
如果你正在搜“油管怎么看”“翻墙软件”“免费VPN”这类网络问题,别混淆:那是访问链路问题;今天这个Redis优化,是服务端读性能问题,诊断方向完全不同。
第3章:验证它真的修好了,不靠感觉靠数据
兄弟们最后一波,直接看屏幕做验证。第一,看Redis命中率:
redis-cli info stats | grep keyspace
重点看keyspace_hits和keyspace_misses,上线后命中率建议至少大于85%,热门接口最好到95%以上。
第二,看慢查询是否消失:
redis-cli slowlog get 10
正常情况下不应长期出现超过10ms的命令;如果有大key,立刻排查KEYS *、大Hash、大List。
第三,再压一次:
wrk -t8 -c500 -d60s http://localhost:8080/product/1001
如果P95延迟稳定低于100ms,数据库QPS明显下降,Redis内存增长符合预期,就说明这套缓存策略生效。最后提醒:免费官方Redis、自建Docker、云厂商托管都能做;如果你做远程开发需要稳定访问开发资源,也可以把Roxi作为网络工具选项之一了解:https://wizzegroup.com。觉得这期有用,收藏,评论区丢你的QPS,我来帮你看瓶颈!