高并发四大手段:缓存、限流、削峰、幂等
来源:SanneSanne
在高并发系统里,这四种手段经常一起出现,但解决的问题完全不同。本文明确阐述它们各自防的是什么风险、在什么场景下发挥作用。
一图总览
| 手段 | 解决什么问题 | 一句话本质 | 典型工具 |
|---|---|---|---|
| 缓存 | 后端太慢、太贵、扛不住重复读 | 少查、快查 | Redis / Memcached / CDN / Local cache |
| 限流 | 请求太多,不能无限往后放 | 超了就拦 | Nginx limit_req / Sentinel / Guava RateLimiter |
| 削峰 | 流量来得太猛,后端一时吃不下 | 先接住,再慢慢消化 | Kafka / RocketMQ / RabbitMQ |
| 幂等 | 同一个动作被执行多次,结果不能错 | 重复执行结果一致 | 去重表 / 分布式锁 / 唯一键 / Token 机制 |
二、缓存 — 解决"同样的数据不要总去查后端"
解决什么问题
缓存最典型的使用场景:高频重复读取。商品详情页、用户资料、首页配置、热门排行榜、系统字典项——这些数据读多写少,短时间被反复访问,对响应速度要求高,每次都查数据库很浪费。
工作机制
无缓存:请求 → 应用 → DB
有缓存:请求 → 应用 → Redis → 未命中 → DB
核心作用:把大量重复读取,变成一次后端查询 + 多次前端命中。
防的核心风险
慢组件被高频重复读打垮——尤其是数据库。数据库天生不适合承受无限放大的高频热点读取。
引入的新挑战
| 问题 | 说明 |
|---|---|
| 缓存穿透 | 查询不存在的数据,每次穿透到 DB |
| 缓存击穿 | 热点 Key 失效,大量请求同时打 DB |
| 缓存雪崩 | 大量 Key 同时失效,请求洪水涌入 DB |
| 数据一致性 | 缓存与数据库数据不一致 |
三、限流 — 解决"请求不能无限往后放"
解决什么问题
系统资源不是无限的。当请求量超过承载上限时,如果不控制入口,后果不是"大家都慢一点",而是:线程池被打满、数据库连接池耗尽、CPU 飙高、内存飙升、雪崩。
常见限流场景
- 某个接口每秒最多允许 1000 次访问
- 某个用户一分钟内最多发 5 次验证码
- 某个 IP 一段时间内请求不能超过阈值
- 秒杀接口只允许一部分请求进入后续链路
防的核心风险
入口流量无限制冲击后端,导致整个系统过载。
限流是保护机制,不是优化机制。它不是为了让系统更快,而是为了让系统在高压下别死。
限流不是提升上限,而是在超过上限时保命。
四、削峰 — 解决"流量不是太多,而是来得太猛"
与限流的区别
| 限流 | 削峰 | |
|---|---|---|
| 关注点 | 总量不能超过承载能力 | 短时间流量冲击太猛 |
| 动作 | 超了就拦 | 太猛先存着,慢慢处理 |
| 典型场景 | 接口限流、用户限流 | 秒杀、报名、抢券 |
工作机制
削峰的思路:先接住,再慢慢处理。
最典型的手段是消息队列(Kafka / RocketMQ / RabbitMQ)。请求先进入队列,后端消费者按自己能承受的速度慢慢消费。
防的核心风险
瞬时洪峰直接打穿后端服务和数据库。
削峰把"瞬时压力"变成"持续压力",让系统能在承载范围内平稳消化流量。
五、幂等 — 解决"同一个动作做多次,结果不能错"
为什么需要幂等
在高并发和分布式系统中,重复几乎不可避免:
- 用户重复点击支付按钮
- 网络超时后客户端重试
- MQ 消息重复投递
- 消费者处理成功但重复消费
- 接口被重复调用
没有幂等的后果
- 一笔订单扣两次库存
- 一笔支付记两次账
- 一张优惠券发两次
- 一条消息触发两次业务动作
防的核心风险
重试、重复提交、重复消费导致业务结果出错。
常见实现方案
| 方案 | 说明 | 适用场景 |
|---|---|---|
| 唯一键约束 | 数据库或 Redis 唯一键防重复插入 | 订单号、流水号 |
| Token 机制 | 前置获取 token,提交时校验并删除 | 表单提交、支付 |
| 去重表 | 额外建一张幂等表记录已处理请求 | MQ 消费者 |
| 分布式锁 | 同一请求加锁防止并发处理 | 资源操作 |
| 状态机 | 业务状态流转限制,同一状态不可重复 | 订单状态变更 |
六、组合实战:秒杀场景
拿秒杀举例,四个手段如何配合:
| 手段 | 做什么 | 防什么风险 |
|---|---|---|
| 缓存 | 商品信息、库存展示放 Redis | 商品页高并发读压垮数据库 |
| 限流 | 限制秒杀入口请求量 | 所有请求冲进系统 |
| 削峰 | 成功抢到的请求写入 MQ,后端慢慢处理 | 订单创建的瞬时洪峰 |
| 幂等 | 防止重复下单、重复扣库存 | 重试和消息重复导致的数据错误 |
七、总结
| 手段 | 本质 | 一句话 |
|---|---|---|
| 缓存 | 少查、快查 | 高频重复读取的缓冲 |
| 限流 | 超了就拦 | 入口的保护闸门 |
| 削峰 | 先接住,再慢慢消化 | 瞬时压力的摊平器 |
| 幂等 | 重复执行结果一致 | 分布式系统的安全带 |
高并发不是靠某一个策略解决的,而是靠一整套手段分别挡住不同方向的风险。
关联页面
| 页面 | 关联点 |
|---|---|
| redis-memory-optimization | Redis 内存优化(缓存的存储层基础) |
| redis-persistence-strategy | Redis 持久化机制(缓存数据的可靠性) |
| nginx-502-504-connection-reset-guide | Nginx 限流配置中的超时与熔断 |
| nginx-security-config-guide | Nginx 安全配置(连接层/请求层限流机制) |
| rate-limiting-algorithms | 5 种限流算法实现详解(计数器/滑动窗口/令牌桶/漏桶/Redis+Lua)——与本文限流部分互补 |
| fullstack-performance-troubleshooting | 全栈性能排障(高并发问题从应用到数据库的全局视角) |
| server-performance-four-dimensions | 服务器性能五维排查(高并发下的系统资源瓶颈分析方法论) |