🛒

电商大促场景下,如何设计 Redis 架构

高并发、热点数据、高可用三大挑战 — 预防 + 容错 + 优化,一图一动画讲透

缓存预热 热点数据 集群高可用 性能优化 熔断降级 监控告警
① 架构总览 ② 缓存预热 ③ 热点数据 ④ 集群高可用 ⑤ 性能优化 ⑥ 熔断降级 ⑦ 监控告警 ⑧ 测一测
架构总览 — 大促 Redis 全景图
大促架构的核心公式:预防(预热 + 本地缓存) + 容错(集群 + 熔断) + 优化(Pipeline + 拆 Key) = 撑住百万 QPS
1 缓存预热 — 大促前把数据搬进 Redis
核心思想:大促开始前,提前将热点商品数据批量写入 Redis。若不预热,大量请求会在活动瞬间穿透到数据库,造成雪崩。

🌡️ 为什么需要预热?

  • 冷启动时 Redis 命中率为 0,所有请求打到 DB
  • DB 瞬时压力是平时的 10~100 倍,极易宕机
  • 预热后命中率可达 95%+

📋 预热策略

  • 提前 1~2h 跑预热脚本,批量 SET 热点商品
  • 按历史访问量排序,优先预热 Top N
  • 分批次预热,避免 Redis 瞬时写压力
  • 设置合理 TTL,活动结束自动失效
2 热点数据处理 — 三把刀

🔪 刀1:拆分热点 Key

大 Key 请求全打到同一个 Redis 节点,单节点成瓶颈。

rank:hot → rank:1 ~ rank:N

读时随机选一个分片,写时广播更新所有分片

🛡️ 刀2:本地缓存

应用层加 Guava Cache / Caffeine,热点数据缓存在 JVM 内存。

访问链路:本地缓存 → Redis → DB,大幅减少 Redis QPS

🔒 刀3:互斥锁

热点 Key 更新时,用 SETNX 加锁,只让一个线程去更新缓存,其余等待或返回旧值。

避免缓存击穿(Key 过期瞬间大量请求打 DB)

🔥 热点 Key 拆分演示

点击 Key 发送请求,观察热点 Key 自动拆分到多个分片
rank:top100
product:flash
coupon:pool
user:hot:001
拆分后的分片 Keys:
请求次数
0
3 集群与高可用 — 三重保障

🌐 Redis Cluster

  • 16384 个 slot 分配给多个主节点
  • 水平扩展,存储和写入线性增长
  • 节点间 Gossip 协议互相探活

👮 Sentinel 哨兵

  • 持续监控主从节点状态
  • 主节点故障时自动选举新主
  • 客户端通过哨兵获取最新主节点地址

🏢 多机房部署

  • 跨机房主从同步,避免单机房故障
  • 同机房读,异机房做灾备
  • 网络分区时优先保证可用性
4 性能优化 — Pipeline / 大 Key / 持久化

⚡ Pipeline 对比:批量发命令 vs 逐条发

Pipeline 把多条命令打包一次性发给 Redis,减少 RTT(Round-Trip Time),吞吐提升 5~10x
❌ 逐条发送(无 Pipeline)
✅ Pipeline 批量发送

🚫 避免大 Key

大 Key(如 Hash 里有百万字段)会导致:

  • 单次操作耗时长,阻塞其他命令
  • 序列化/反序列化慢,内存不连续
  • 迁移、持久化时产生巨大 IO 压力
方案:HGETALLHSCAN 分批读;大 Hash 拆成多个小 Hash

💾 持久化调优

  • AOF everysec:每秒 fsync,最多丢 1s 数据,性能影响小
  • 关闭 RDB(或低频触发):大促期间 RDB fork 子进程会产生 Copy-on-Write 压力
  • 内存充足时开 no-appendfsync-on-rewrite yes,AOF 重写时不阻塞主线程
5 熔断与降级 — Redis 挂了怎么办?

⚡ 熔断(Circuit Breaker)

Redis 异常率超过阈值时,立即断开对 Redis 的请求,直接返回兜底数据或报错,避免大量请求堆积引发雪崩

常用框架:Sentinel(阿里)、Hystrix(Netflix)、Resilience4j

🪂 降级(Fallback)

Redis 不可用时,按优先级降级:

  • 1️⃣ 本地缓存(Guava Cache / Caffeine)
  • 2️⃣ 返回默认值或空数据
  • 3️⃣ 降级到数据库(加限流保护)
  • 4️⃣ 降级到静态页面 / CDN

🔌 熔断器状态机演示

点击状态切换,了解熔断器三态转换

CLOSED(正常)
请求正常通过 Redis
🚨
OPEN(熔断)
直接拒绝,走降级逻辑
🔶
HALF-OPEN(探测)
放少量请求试探 Redis
当前:CLOSED 状态 — Redis 正常服务,所有请求通过
6 监控与日志 — 大促期间的眼睛
慢查询日志:开启 slowlog-log-slower-than 10000(单位微秒),记录超过 10ms 的命令。 重点排查 HGETALLSMEMBERSSORT 等全量操作,用 HSCAN/SSCAN 替代。

📊 必监控指标

  • QPS(命令/秒)— 告警阈值:> 80% 峰值容量
  • 内存使用率 — 告警阈值:> 80%
  • 命中率(hit_rate)— 告警阈值:< 90%
  • 连接数 — 告警阈值:> maxclients × 80%
  • 主从复制延迟(replication_lag)
  • 慢查询数量(slowlog_len 变化速率)

🚨 告警分级

  • P2 警告:内存 > 70%,QPS > 70% 峰值容量
  • P1 严重:主从延迟 > 10s,命中率 < 85%
  • P0 紧急:主节点不可用,内存 OOM,熔断触发

工具栈:Prometheus + Grafana + Redis Exporter + PagerDuty

测一测,你学会了吗?
Q1. 大促前缓存预热的核心目的是什么?
A减少 Redis 内存占用
B提前加载热点数据,避免大量请求穿透到数据库造成雪崩
C给 Redis 集群做数据均衡
Q2. 热点 Key 拆分后,写操作应该怎么处理?
A随机写一个分片,其他分片靠过期自动失效
B广播更新所有分片,保证一致性
C只写原始 Key,分片只读不写
Q3. 大促期间为什么建议关闭 RDB 或降低 RDB 频率?
ARDB 会清空内存中的数据
BRDB 不支持大促场景
CRDB fork 子进程产生 Copy-on-Write,大促高写入时 COW 内存翻倍,影响主进程性能
Q4. 熔断器从 OPEN 状态变为 CLOSED 状态,需要经过哪个中间状态?
APAUSED(暂停)
BHALF-OPEN(半开)
CSTANDBY(待机)
面试一句话总结:大促 Redis 架构 = 预防(缓存预热 + 本地缓存)+ 容错(Cluster + Sentinel + 熔断降级)+ 优化(Pipeline + 拆 Key + 持久化调优)+ 可观测(QPS/内存/命中率监控)
🔥

预防

缓存预热 + 本地缓存 + 互斥锁,防止缓存穿透/击穿/雪崩

🛡️

容错

Redis Cluster + Sentinel + 多机房 + 熔断降级,保证高可用

优化

Pipeline + 避免大 Key + AOF everysec,压榨每一毫秒性能