系统设计应从问题和约束开始,不是从“要不要上微服务、Kafka、Kubernetes”开始。一个清楚的方案要说明流量、数据量、一致性、可用性、成本和团队能力。
一套九步顺序
- 明确用户、核心场景和不做什么。
- 区分功能需求与非功能需求。
- 估算峰值 QPS、数据量、带宽和增长。
- 画出读写主链路与外部依赖。
- 设计数据模型、一致性和幂等。
- 找出单点、热点和过载路径。
- 定义缓存、异步、扩容与降级。
- 定义监控、发布、备份和恢复。
- 记录取舍、风险和演进条件。
容量估算示例
假设每天 200 万次请求,峰值是平均值的 8 倍:
1 | 平均 QPS = 2,000,000 / 86,400 ≈ 23 |
再根据单实例压测容量、冗余系数、请求大小和下游限制估算实例、连接和带宽。估算不是追求个位数准确,而是提前发现数量级错误。
SLI、SLO、SLA 与错误预算
- SLI:实际测量指标,例如成功请求比例。
- SLO:内部可靠性目标,例如 30 天成功率目标。
- SLA:对外承诺及可能的补偿条款。
- Error Budget:目标允许的失败空间。
有错误预算不代表可以随意失败,而是用来平衡可靠性投入和发布速度。
RTO 与 RPO
RTO 是故障后允许多长时间恢复服务;RPO 是最多允许丢失多长时间的数据。每晚备份一次意味着最坏可能丢一天数据,未必满足关键订单系统的 RPO。
1 | 高可用:尽量不中断 |
三者不能互相替代,复制也会复制误删除和错误写入。
复制、分区与分片
- 复制:同一份数据保留多个副本,提高可用性和读能力。
- 分区:按规则组织一张表或日志的数据。
- 分片:把数据分散到多个独立存储节点。
- 读模型:为特定查询预先组织适合读取的数据。
分片会引入跨分片查询、事务、扩容和热点问题,应在单库索引、归档、读写分离和垂直拆分不足时再考虑。
用 ADR 记录决策
架构决策记录(Architecture Decision Record)至少包含:背景、约束、候选方案、最终选择、正负影响和复审条件。
1 | 决策:先采用模块化单体 |
ADR 记录为什么这样选,不是复制配置手册。