2. Redis 在削峰中的核心角色
在业务削峰场景中,Redis 并非简单的缓存加速器,而是承担了缓冲层、异步处理器、请求排队器、数据库协同器四个关键角色。这四个角色共同构成了削峰系统的核心骨架,决定了系统能否在流量洪峰下保持稳定。
2.1 角色总览与职责矩阵
下表从职责、数据结构、典型场景三个维度,对比 Redis 在削峰中的四大核心角色:
| 核心角色 | 核心职责 | 主要数据结构 | 典型场景 |
|---|---|---|---|
| 缓冲层 | 瞬时承接写流量,平摊写入压力 | List、Stream | 秒杀订单写入、日志收集 |
| 异步处理器 | 解耦请求处理与响应,提升吞吐 | Stream、Pub/Sub | 异步扣库存、消息通知 |
| 请求排队器 | 公平/优先级排队,控制并发度 | ZSet、List + Lua | 抢购资格排队、任务调度 |
| 数据库协同器 | 保护数据库,保证最终一致性 | String、Hash、Lua | 库存预扣、订单防重 |
2.2 缓冲层:瞬时流量的第一道防线
当流量峰值远超数据库处理能力时,Redis 作为内存缓冲层,以微秒级写入速度承接所有请求,将数据暂存在内存队列中,再由后端消费者按可控速率拉取处理。这种设计将“瞬时洪峰”转化为“平缓水流”。
关键指标:Redis 单节点 List 写入吞吐可达 10 万+ QPS,是 MySQL 单机写入能力的 50~100 倍。
缓冲层典型实现——基于 Redis List 的 FIFO 队列:
// 生产者:秒杀请求入队
LPUSH seckill:order:queue "{userId:1001, skuId:2001, ts:1700000000}"
// 消费者:定时批量拉取(每 100ms 拉取 500 条)
BRPOP seckill:order:queue 0 // 阻塞获取单条
// 或 LRANGE + LTRIM 批量消费
2.3 异步处理器:解耦与削峰的核心机制
异步处理将“请求-响应”链路拆分为两个阶段:请求阶段只做数据入队和快速响应;处理阶段由后台 Worker 异步完成。Redis Stream 提供了比 List 更完善的异步消息模型,支持消费者组、消息确认、消息回溯。
实践建议:优先使用 Redis Stream 而非 Pub/Sub 做异步削峰。Stream 支持消息持久化和 ACK 机制,Pub/Sub 在消费者离线时会丢失消息,不适合关键业务。
异步处理流程对比:
| 维度 | 同步处理 | 异步处理(Redis Stream) |
|---|---|---|
| 响应时间 | 等待数据库写入完成,RT 高 | 仅入队即返回,RT 极低 |
| 数据库压力 | 瞬时并发写入,易打满连接池 | Worker 匀速写入,压力可控 |
| 失败处理 | 请求失败直接返回错误 | 消息可重试、可补偿 |
| 吞吐上限 | 受限于数据库写入能力 | 受限于 Redis 内存 + Worker 数 |
2.4 请求排队器:公平性与优先级控制
当资源有限(如库存 100 件,请求 10 万),必须通过排队控制并发。Redis ZSet 利用 score 实现优先级排队,List 实现公平 FIFO 排队。排队器确保系统不会因瞬时并发而崩溃,同时提供可预期的服务等级。
基于 ZSet 的优先级排队示例:
// 入队:score = 时间戳(毫秒),实现 FIFO
ZADD seckill:queue:priority 1700000000001 "user:1001"
ZADD seckill:queue:priority 1700000000002 "user:1002"
// 出队:取 score 最小的 N 个
ZRANGE seckill:queue:priority 0 99 WITHSCORES
// 处理完成后删除
ZREM seckill:queue:priority "user:1001"
避坑:ZSet 的 ZRANGE 与 ZREM 不是原子操作,高并发下可能出现多个 Worker 取到相同元素。必须使用 Lua 脚本或 Redis 分布式锁保证出队原子性。
2.5 与数据库的协同:最终一致性保障
Redis 削峰不能脱离数据库独立存在。两者协同的核心原则是:Redis 负责流量承接与快速判断,数据库负责最终落盘与强一致性。协同模式通常分为三步:
- 预校验:在 Redis 中检查库存、资格等前置条件(内存操作,微秒级)。
- 预占/预扣:在 Redis 中原子扣减资源(Lua 脚本保证原子性)。
- 异步落库:Worker 从 Redis 拉取数据,写入数据库,并做最终一致性校验。
协同过程中的数据一致性保障策略:
| 场景 | Redis 操作 | 数据库操作 | 一致性保障 |
|---|---|---|---|
| 库存预扣 | DECR 扣减库存 | UPDATE 扣减库存 | Redis 库存 >= 数据库库存,定时对账 |
| 订单去重 | SADD 记录订单号 | INSERT 订单记录 | Redis 存在则数据库跳过,防止重复 |
| 超时回滚 | ZSet 记录过期时间 | 回滚未支付订单 | Redis 过期事件触发数据库回滚 |
2.6 四大角色协同架构图
下图展示了 Redis 在削峰系统中四大角色的协同关系与数据流向:
2.7 角色选择决策树
在实际业务中,并非所有场景都需要四个角色同时部署。以下决策树帮助根据业务特征选择核心角色:
- 流量瞬时峰值 > 数据库 5 倍以上 → 必须部署 缓冲层,否则数据库直接被打满。
- 业务允许延迟处理(秒~分钟级) → 引入 异步处理器,大幅提升系统吞吐。
- 资源有限且需要公平分配 → 引入 请求排队器,防止抢购场景下的“饥饿”问题。
- Redis 与数据库数据需要强最终一致性 → 必须部署 数据库协同器,通过 Lua 脚本和定时对账保证数据不丢失、不重复。
实战经验:在双十一秒杀场景中,四个角色缺一不可。缓冲层承接 100 万 QPS 写入,排队器控制并发为 5000 QPS,异步处理器以 2000 TPS 写入数据库,协同器保证库存最终一致。任何一个角色缺失,系统都会在流量洪峰下崩溃。