1. 削峰填谷概述
1.1 什么是业务削峰
业务削峰(Peak Clipping)是指通过技术手段,将瞬时高并发请求产生的流量高峰进行“削平”,使流量以更平稳、可控的速率向后端系统传递,从而避免系统因瞬时压力过载而崩溃。削峰的核心思想是“用时间换空间”——允许请求在入口处短暂排队或延迟,换取后端资源的稳定输出。
核心公式: 削峰率 = (原始峰值 QPS − 削峰后 QPS) / 原始峰值 QPS × 100%。典型目标削峰率在 60%~90% 之间。
1.2 为什么需要削峰
互联网业务流量具有明显的“潮汐效应”——平时流量平稳,但在特定时刻(如秒杀开始、抢票开售)会瞬间爆发。如果不做削峰,后端系统将面临以下风险:
| 风险维度 | 具体表现 | 后果严重性 |
|---|---|---|
| 数据库过载 | 瞬时写入 QPS 超过数据库连接池上限 | 连接耗尽 → 服务不可用 |
| 缓存击穿 | 热点 Key 在峰值瞬间失效,大量请求穿透到 DB | 数据库被打垮 → 雪崩 |
| 网络带宽打满 | 响应数据量过大,出口带宽被占满 | 请求超时 → 用户重试 → 恶性循环 |
| 应用线程阻塞 | Tomcat/Jetty 线程池被占满,新请求排队 | 请求堆积 → 内存溢出 → 进程重启 |
| 资源成本失控 | 为应对峰值而扩容,峰值过后资源闲置 | 硬件成本浪费 3~5 倍 |
经验数据: 未做削峰的系统,在峰值流量达到平时 10 倍时,故障概率超过 85%;做了削峰后,同样流量下故障概率可降至 5% 以下。
1.3 削峰的典型业务场景
削峰技术广泛应用于以下三类典型场景,每类场景对削峰的要求和实现方式各有侧重:
场景一:秒杀系统
- 流量特征: 开售瞬间流量陡增,峰值 QPS 可达平时的 100~1000 倍
- 核心矛盾: 商品数量有限(如 100 件),但请求量巨大(如 1000 万次)
- 削峰策略: 前端限流 + 后端排队 + 库存预扣 + 异步落单
- 典型指标: 削峰率 90%+,最终一致性可接受
场景二:抢票系统
- 流量特征: 多时段、多车次同时开售,流量呈多峰分布
- 核心矛盾: 余票实时性要求高,且需防止“占座不付”
- 削峰策略: 队列削峰 + 库存分段释放 + 支付超时回收
- 典型指标: 削峰率 70%~80%,需保证数据强一致性
场景三:预约系统
- 流量特征: 预约开放瞬间流量集中,但持续时间较长(分钟级)
- 核心矛盾: 预约资格有限,需公平分配且防止黄牛刷单
- 削峰策略: 令牌桶限流 + 滑动窗口 + 用户维度去重
- 典型指标: 削峰率 60%~70%,需结合风控策略
1.4 削峰的核心技术手段
在实际业务中,削峰通常不是单一技术,而是多种手段的组合。以下是 Redis 生态中最常用的削峰技术栈:
| 技术手段 | 实现原理 | 适用场景 | Redis 核心数据结构 |
|---|---|---|---|
| 令牌桶限流 | 以固定速率生成令牌,请求需获取令牌才能通过 | 预约、秒杀预热 | String + Lua 脚本 |
| 漏桶限流 | 请求进入桶中,以固定速率流出,溢出则丢弃 | 抢票、API 网关 | List + ZSet |
| 队列削峰 | 请求先入队列,后端 worker 按能力消费 | 秒杀、异步下单 | List / Stream |
| 库存预扣 | 先扣减 Redis 库存,异步同步到数据库 | 秒杀、抢票 | String (DECR) + Lua |
| 滑动窗口 | 基于时间窗口统计请求量,超过阈值则拒绝 | 预约、防刷 | ZSet (时间戳排序) |
重要提醒: 削峰不是“消灭峰值”,而是“转移峰值”。削峰后的流量仍然需要后端系统具备相应的处理能力。如果后端处理能力不足,削峰只会将崩溃从“瞬时”变为“持续”。因此,削峰必须与后端容量评估、异步处理、降级预案配合使用。
1.5 削峰填谷的衡量指标
在实际项目中,我们通过以下指标来衡量削峰方案的效果:
- 峰值削平率: (原始峰值 QPS − 削峰后 QPS) / 原始峰值 QPS。理想值 ≥ 80%。
- 请求成功率: 削峰后成功处理的请求占比。需 ≥ 99.9%。
- 平均响应时间: 削峰后请求的平均处理耗时。应控制在 200ms 以内。
- 资源利用率: 削峰后 CPU、内存、网络带宽的峰值利用率。应 ≤ 70%。
- 数据一致性延迟: 异步处理场景下,数据从 Redis 同步到数据库的最大延迟。应 ≤ 5 秒。
实战建议: 在开始设计削峰方案前,先通过压测获取系统的真实承载能力(如数据库最大 QPS、应用线程池上限),然后以“后端承载能力 × 安全系数(0.7~0.8)”作为削峰后的目标 QPS,反向推导削峰策略的参数配置。