以下内容面向高并发业务与云边协同场景,聚焦“可落地、可度量、可扩展”。如无特别说明,示例基于 redis-cli 或常见客户端实现。🚀
场景—能力—风险对照表(落地速览)
| 场景 | 核心结构/命令 | 设计要点 | 典型指标/目标 | 风险与边界 |
|---|---|---|---|---|
| 旁路缓存(读多写少) | GET / SETEX | <span style="color:red">TTL</span> 分层、热点预热、失效回填 | P95 延迟降低、缓存命中率 ≥ <span style="color:red">90%</span> | <span style="color:red">雪崩/击穿/穿透</span> |
| 防缓存穿透 | RedisBloom BF.ADD/EXISTS | 先判存在性再查库 | 降低空击 ≥ <span style="color:red">95%</span> | 需加载模块、假阳性可接受 |
| 热点Key治理 | <span style="color:red">本地缓存</span> + Redis、读写隔离 | 多级缓存、<span style="color:red">随机TTL</span> | 降峰 | 版本一致性 |
| 分布式锁 | SET key val NX PX + Lua 释放 | <span style="color:red">唯一值</span>+过期+原子释放 | 单资源互斥 | 时钟漂移、锁失效 |
| 限流/风控 | INCR + 过期 / Lua / Redis Functions | 固定/滑动/令牌桶 | 稳住 QPS、<span style="color:red">熔断</span>保护 | 维度爆炸 |
| 排行榜/Feed | ZADD/ZREVRANGE | <span style="color:red">Sorted Set</span> 按分数排序 | T+实时榜单 | N 大时内存占用 |
| 事件流队列 | <span style="color:red">Streams</span> XADD/XREADGROUP | 消费组、ACK、死信 | 消息有序/可回溯 | 消费堆积处理 |
| 会话/鉴权 | SETEX/HSET | 轻会话、黑名单 | 登出实时生效 | 跨端一致 |
| 计数与UV | HINCRBY / <span style="color:red">HyperLogLog</span> | 精确/近似并存 | UV 误差可控 | 近似误差容忍 |
| 地理/就近调度 | GEOADD/GEORADIUS | LBS 场景、<span style="color:red">就近</span>访问 | 距离查询 | 半径/精度限制 |
关键方案与代码(含解释)
1) 旁路缓存(Cache-Aside)与热点保护 ⚡
# 读:查缓存 → 未命中查库 → 回填并设置随机TTL,降低同时失效
GET product:123
# 未命中后回填
SETEX product:123 $((600 + RANDOM%120)) "json-payload"解释:SETEX 直接设置值与 TTL,加入<span style="color:red">随机 TTL</span>避免同刻同时过期导致<span style="color:red">雪崩</span>。回填数据建议携带版本号或 ETag,便于灰度与回滚。
工作流(vditor/mermaid 支持):
2) 分布式锁(互斥与幂等)🔒
# 加锁:确保唯一值 + 过期时间(毫秒)
SET lock:order:987 "uuid-xyz" NX PX 10000
# 释放:仅持有者可删,Lua 保证原子性
EVAL "if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else return 0 end" 1 lock:order:987 uuid-xyz解释:用 SET NX PX 获取锁,值为<span style="color:red">唯一标识</span>,防止误删他人锁;释放用 Lua 比较再删,确保<span style="color:red">原子</span>。对跨机房强一致锁,需评估 RedLock 的容错假设与时钟风险,关键路径更宜用队列串行化或单点协调。
3) 固定窗口限流(简单可依赖)🛡️
# 以用户ID为维度,1分钟最多100次
local key = "rl:"..ARGV[1]..":"..(math.floor(redis.call('TIME')[1]/60))
local cur = redis.call('INCR', key)
if cur == 1 then redis.call('EXPIRE', key, 60) end
return cur解释:按<span style="color:red">固定窗口</span>聚合,首次 INCR 时设置 60s 过期,返回计数;超过阈值在业务侧拒绝或降级。对“边界抖动”可升级至<span style="color:red">滑动窗口或令牌桶</span>(Lua/Redis Functions 持久化脚本库,便于版本管理)。
速算公式:若阈值R,窗口T秒,则理论上限 QPS ≈ <span style="color:red">R/T</span>。滑动窗口、令牌桶能平滑瞬时峰值。
4) 排行榜/计分板(Sorted Set)📈
# 增加积分并入榜
ZINCRBY rank:season1 30 user:42
# 取前10名
ZREVRANGE rank:season1 0 9 WITHSCORES解释:Sorted Set 以分数排序,适用于分数可变、需要快速 TopN 的场景;大榜建议分片(按前缀或区间)并定期<span style="color:red">压缩/归档</span>,避免内存膨胀。
5) 事件流/异步解耦(Redis Streams)🧠
# 生产消息
XADD stream:order * orderId 987 status created
# 创建消费组
XGROUP CREATE stream:order cgrp0 $ MKSTREAM
# 消费(从组内)
XREADGROUP GROUP cgrp0 c1 COUNT 10 BLOCK 2000 STREAMS stream:order >
# 处理成功后确认
XACK stream:order cgrp0 <message-id>解释:Streams 提供<span style="color:red">消费组</span>与待处理队列,支持“<span style="color:red">至少一次</span>”投递与回溯。需监控 <span style="color:red">PEL</span>(未确认条目)并设计重试/死信队列。
6) 防穿透(RedisBloom,需模块)🧪
# 初始化过滤器(只需一次)
BF.RESERVE bf:user 0.01 1000000
# 写入/检查
BF.ADD bf:user u:123
BF.EXISTS bf:user u:123解释:布隆过滤器以<span style="color:red">极低内存</span>换取近似存在判断,0.01 表示目标假阳性率。适合“先判存在再查库”以降低<span style="color:red">空击</span>与下游压力。
选型与治理要点(务实结论)
- 优先级:读多写少优先上缓存,写多读多评估一致性成本;跨域事务慎用锁,尽量改造为幂等+异步。
- 稳定性:必做<span style="color:red">限流、熔断、降级</span>三件套;TTL 随机化、预热、批量回填,避免集中抖动。
- 成本:Key 设计短小、结构紧凑;超大对象分片/压缩;冷数据落盘或外置存储(例如对象存储)。
- 观测:埋点 <span style="color:red">命中率/慢查询/内存碎片/大Key</span>;自动巡检与告警阈值分级。
- 前瞻:充分利用 <span style="color:red">Redis Functions</span>(持久化脚本库)沉淀限流、幂等、记分等原语,做到“平台化复用”。
小结(面向业务的判断标准)✅
当你的目标是 极低延迟、强韧性、弹性削峰,Redis 是“第一梯队”组件;当你的诉求偏向 强一致长事务、超大对象、复杂聚合,应转向数据库/搜索/消息总线等更合适的系统,再由 Redis 做“前排加速层”。
坚持一个原则:把<span style="color:red">简单正确</span>做成平台能力,把<span style="color:red">复杂偶发</span>隔离在边缘流程。这样,性能与可用性都会稳稳落地。✨
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。