高并发与高可用
高并发与高可用是大型在线系统的两项核心能力:
- 高并发(High Concurrency):系统同时处理大量进行中请求的能力。
- 高吞吐(High Throughput):系统单位时间内完成有效工作的数量。
- 高可用(High Availability):系统在组件故障、流量变化和日常变更中持续提供服务的能力。
高并发关注系统在负载上升时的容量和延迟,高可用关注系统在故障条件下的成功率和恢复能力。两者共同受 CPU、内存、网络、存储、下游依赖和故障余量约束。
高并发与高可用的关系
流量上升后,系统通常先出现资源利用率升高和请求排队,随后是尾延迟、超时与重试。如果没有限流、背压和降级,过载会使实例失联并减少有效容量,最终演变为可用性事故。
参考:Google SRE:Addressing Cascading Failures 与 The Tail at Scale
高可用设计同样依赖容量。为了容忍实例、节点或可用区故障,剩余副本必须有足够余量接管流量。正常状态下运行水位过高,即使部署了多个副本,故障转移后仍可能立即过载。
核心指标
| 指标 | 含义 | 关注点 |
|---|---|---|
| QPS / TPS | 每秒请求数或事务数 | 区分入口流量和成功完成量 |
| 并发数 | 某一时刻系统中的请求数 | 包括排队、计算和等待 I/O |
| 吞吐量 | 单位时间完成的工作 | 同时观察错误和超时 |
| Goodput | 在时限内正确完成的有效工作 | 排除失败、超时和无效重试 |
| 延迟 | 单次操作从开始到完成的时间 | 观察 P50、P95、P99 |
| 可用性 | 满足成功条件的事件比例 | 以用户结果而非进程存活定义 |
| 容量 | 在目标 SLO 下可持续承载的最大负载 | 区分稳态、突发和压垮点 |
系统即使接收了 10 万 QPS,如果多数请求最终超时,Goodput 依然很低。容量测试应以满足延迟和错误率目标的最大有效负载为结论。
总体设计
参考:Google SRE:Embracing Risk 与 AWS Well-Architected Reliability Pillar
设计从用户目标开始:
- 使用 SLI 和 SLO 定义成功率、延迟、正确性与数据恢复目标。
- 根据正常峰值和故障场景估算容量。
- 通过缓存、异步化、分片和水平扩展提高处理能力。
- 使用限流、背压、隔离、熔断和降级限制故障范围。
- 用负载测试、故障演练和恢复演练验证设计。
高并发
高并发设计主要处理容量、延迟和过载:
- 使用 Little 定律估算请求速率、响应时间和在途请求数的关系;
- 降低单次请求的 CPU、内存、网络和存储成本;
- 使用缓存减少重复计算和回源请求;
- 使用消息队列把非关键工作移出同步请求链路;
- 通过无状态化、水平扩展和数据分片扩大总容量;
- 使用有界队列、并发限制、负载丢弃和重试预算保护 Goodput;
- 对 P99 延迟、热点分片和自动扩容滞后进行专项测试。
详细内容见高并发系统设计。
高可用
高可用设计主要处理故障隔离和恢复:
- 使用请求成功率、延迟、正确性等指标定义 SLO;
- 识别实例、节点、可用区、区域和共享依赖等故障域;
- 跨故障域部署冗余副本,并为故障转移保留容量;
- 区分启动、存活和就绪状态,避免错误健康检查放大故障;
- 明确数据复制、一致性、RPO、RTO 和备份恢复策略;
- 使用金丝雀发布、分批变更和优雅下线限制发布风险;
- 定期执行故障转移、数据恢复和大规模过载演练。
详细内容见高可用系统设计。
设计示例
以订单 API 为例,设计目标如下:
- 正常流量 2,000 QPS,峰值 5,000 QPS;
- 99.9% 的合法请求成功;
- 99% 的请求在 300 ms 内完成;
- 单个实例、节点或可用区故障时仍满足核心 SLO;
- 已确认订单的数据恢复点目标(RPO)为 0。
系统设计需要回答:
| 问题 | 对应设计 |
|---|---|
| 5,000 QPS、300 ms 下有多少在途请求 | Little 定律、并发限制、连接池 |
| 单个可用区退出后能否承载峰值 | 故障容量、跨区负载均衡 |
| 库存服务变慢时如何保护订单服务 | 超时、隔离、熔断、降级 |
| 超出容量时如何处理请求 | 限流、有界队列、负载丢弃 |
| 数据库切换时如何处理未知结果 | 幂等键、重试语义、状态查询 |
| 如何确认系统仍满足目标 | SLI、链路追踪、负载与故障测试 |
设计原则
- 先定义 SLO,再确定容量和架构。
- 容量以 Goodput 和尾延迟衡量,不以压垮点衡量。
- 队列用于吸收有限突发,不能解决长期容量不足。
- 自动扩容之前仍需要容量余量和过载保护。
- 副本必须跨故障域部署,并消除共享单点。
- 故障转移同时需要冗余副本和冗余容量。
- 降级、恢复和回滚路径必须定期执行。
参考资料
- Google SRE Book:Addressing Cascading Failures
- Google SRE Book:Embracing Risk
- Jeffrey Dean、Luiz André Barroso:The Tail at Scale
- AWS:Well-Architected Reliability Pillar
- Google SRE Workbook:Implementing SLOs