Skip to content

系统设计模板

系统设计面试的通用思路与模板

设计方法论

四步法

┌─────────────────────────────────────────────────────────────┐
│                    系统设计四步法                            │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  1. 需求澄清 (5-10 min)                                     │
│     - 功能需求:核心功能是什么?                             │
│     - 非功能需求:性能、可用性、一致性要求                   │
│     - 规模估算:用户量、数据量、QPS                          │
│                                                              │
│  2. 高层设计 (10-15 min)                                    │
│     - 绘制系统架构图                                         │
│     - 确定核心组件                                           │
│     - 定义 API 接口                                          │
│                                                              │
│  3. 详细设计 (15-20 min)                                    │
│     - 数据模型设计                                           │
│     - 核心算法/流程                                          │
│     - 关键组件深入                                           │
│                                                              │
│  4. 扩展讨论 (5-10 min)                                     │
│     - 扩展性方案                                             │
│     - 容错处理                                               │
│     - 监控告警                                               │
│                                                              │
└─────────────────────────────────────────────────────────────┘

规模估算

常用数据:
- 1 天 = 86,400 秒 ≈ 100,000 秒
- 1 年 ≈ 365 天
- QPS 峰值 ≈ 平均 QPS × 2~3

存储估算:
- 1 KB = 1,000 字节
- 1 MB = 1,000 KB
- 1 GB = 1,000 MB
- 1 TB = 1,000 GB

网络带宽:
- 1 Gbps = 125 MB/s
- 单机 MySQL QPS ≈ 1,000~5,000
- 单机 Redis QPS ≈ 100,000

示例计算:
DAU = 1000万
每人每天 10 次请求
总请求 = 1亿/天
平均 QPS = 1亿 / 86400 ≈ 1,200
峰值 QPS ≈ 3,600

通用架构模式

1. 读写分离

┌─────────────────────────────────────────────────────────────┐
│                                                              │
│   ┌─────────┐      ┌─────────┐      ┌─────────┐            │
│   │  Client │      │  Client │      │  Client │            │
│   └────┬────┘      └────┬────┘      └────┬────┘            │
│        │                │                │                  │
│        └────────────────┼────────────────┘                  │
│                         │                                    │
│                  ┌──────▼──────┐                            │
│                  │   Gateway   │                            │
│                  └──────┬──────┘                            │
│                         │                                    │
│         ┌───────────────┼───────────────┐                   │
│         │ 写            │ 读            │                   │
│   ┌─────▼─────┐   ┌─────▼─────┐  ┌─────▼─────┐            │
│   │  Master   │──▶│  Slave 1  │  │  Slave 2  │            │
│   │  (写库)   │   │  (读库)   │  │  (读库)   │            │
│   └───────────┘   └───────────┘  └───────────┘            │
│                                                              │
└─────────────────────────────────────────────────────────────┘

适用场景:读多写少
注意事项:主从延迟、数据一致性

2. 缓存架构

┌─────────────────────────────────────────────────────────────┐
│                    缓存策略                                  │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Cache-Aside(旁路缓存):                                  │
│  读:先读缓存 → 未命中 → 读 DB → 写缓存                    │
│  写:更新 DB → 删除缓存                                     │
│                                                              │
│  Read-Through:                                             │
│  读:只读缓存,缓存负责从 DB 加载                           │
│                                                              │
│  Write-Through:                                            │
│  写:写缓存,缓存同步写 DB                                  │
│                                                              │
│  Write-Behind:                                             │
│  写:写缓存,缓存异步写 DB                                  │
│                                                              │
└─────────────────────────────────────────────────────────────┘

多级缓存:
┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐
│ Browser │ →  │  CDN    │ →  │  Redis  │ →  │  MySQL  │
│ Cache   │    │         │    │         │    │         │
└─────────┘    └─────────┘    └─────────┘    └─────────┘

3. 消息队列

┌─────────────────────────────────────────────────────────────┐
│                    消息队列架构                              │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│   同步调用(问题):                                        │
│   A → B → C → D (链路长、耦合高、可用性差)               │
│                                                              │
│   异步解耦:                                                │
│   ┌───┐    ┌─────────┐    ┌───┐                            │
│   │ A │ →  │   MQ    │ →  │ B │                            │
│   └───┘    │         │    ├───┤                            │
│            │         │ →  │ C │                            │
│            │         │    ├───┤                            │
│            │         │ →  │ D │                            │
│            └─────────┘    └───┘                            │
│                                                              │
│   应用场景:                                                │
│   - 异步处理:注册后发送邮件                                │
│   - 削峰填谷:秒杀订单                                      │
│   - 服务解耦:订单 → 库存、积分、通知                      │
│                                                              │
└─────────────────────────────────────────────────────────────┘

4. 分库分表

┌─────────────────────────────────────────────────────────────┐
│                    分库分表策略                              │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  垂直拆分(按业务):                                       │
│  ┌─────────┐         ┌─────────┐  ┌─────────┐             │
│  │  用户表  │         │  用户库  │  │  订单库  │             │
│  │  订单表  │   →     │  用户表  │  │  订单表  │             │
│  │  商品表  │         └─────────┘  │  商品表  │             │
│  └─────────┘                      └─────────┘             │
│                                                              │
│  水平拆分(按数据):                                       │
│  ┌─────────────┐         ┌────────┐  ┌────────┐           │
│  │  订单表      │         │订单表_0│  │订单表_1│           │
│  │  1亿条数据   │   →     │ 5000万 │  │ 5000万 │           │
│  └─────────────┘         └────────┘  └────────┘           │
│                                                              │
│  分片策略:                                                 │
│  - 范围分片:id 0-1000万 → db0,1000万-2000万 → db1        │
│  - 哈希分片:hash(user_id) % 4                             │
│  - 一致性哈希:虚拟节点                                     │
│                                                              │
└─────────────────────────────────────────────────────────────┘

经典场景模板

短链系统

需求:
- 长 URL → 短 URL
- 短 URL → 长 URL(重定向)
- QPS: 10万生成/天,1000万访问/天

架构:
┌─────────┐    ┌───────────┐    ┌─────────┐    ┌─────────┐
│ Client  │ →  │  Gateway  │ →  │  Redis  │ →  │  MySQL  │
└─────────┘    └───────────┘    │ (缓存)  │    │ (持久化)│
                                └─────────┘    └─────────┘

核心设计:
1. 短码生成:
   - 自增 ID + Base62 编码
   - 预生成 ID 池

2. 存储:
   - MySQL: short_code, long_url, created_at
   - Redis: short_code → long_url

3. 重定向:
   - 301 永久重定向(可缓存)
   - 302 临时重定向(可统计)

API:
POST /shorten   { "url": "https://..." }
GET  /{code}    → 302 重定向

秒杀系统

需求:
- 短时间高并发抢购
- 库存扣减准确
- 防止超卖

架构:
┌─────────────────────────────────────────────────────────────┐
│                                                              │
│  ┌─────────┐    ┌───────┐    ┌───────┐    ┌───────────┐   │
│  │  CDN    │ →  │ Nginx │ →  │  App  │ →  │   Redis   │   │
│  │(静态页面)│    │(限流) │    │Server │    │(库存/令牌)│   │
│  └─────────┘    └───────┘    └───────┘    └───────────┘   │
│                                              │              │
│                              ┌───────────────▼───────────┐ │
│                              │         MQ               │ │
│                              │   (异步处理订单)          │ │
│                              └───────────────┬───────────┘ │
│                                              │              │
│                              ┌───────────────▼───────────┐ │
│                              │       订单服务            │ │
│                              │   (创建订单、扣库存)      │ │
│                              └───────────────────────────┘ │
│                                                              │
└─────────────────────────────────────────────────────────────┘

核心设计:
1. 前端:
   - 静态页面 CDN 缓存
   - 按钮置灰防重复点击
   - 验证码/答题

2. 接入层:
   - Nginx 限流
   - 用户频率限制

3. 服务层:
   - Redis 预扣库存(原子操作)
   - 令牌桶/漏桶限流
   - 请求入队列

4. 数据层:
   - 库存扣减用 Lua 脚本
   - 最终一致性

库存扣减 Lua 脚本:
if redis.call('get', KEYS[1]) >= ARGV[1] then
    return redis.call('decrby', KEYS[1], ARGV[1])
else
    return -1
end

消息推送系统

需求:
- 实时推送消息
- 支持百万级在线用户
- 消息可靠送达

架构:
┌─────────────────────────────────────────────────────────────┐
│                                                              │
│  ┌─────────┐    ┌───────────┐    ┌───────────────────────┐ │
│  │ 业务系统 │ →  │    MQ     │ →  │      推送服务        │ │
│  └─────────┘    └───────────┘    │  (连接管理、消息分发) │ │
│                                   └───────────┬───────────┘ │
│                                               │              │
│                           ┌───────────────────┼──────────┐  │
│                           │                   │          │  │
│                   ┌───────▼────┐      ┌──────▼─────┐    │  │
│                   │ WebSocket  │      │   APNS/    │    │  │
│                   │   连接池   │      │   FCM      │    │  │
│                   └───────┬────┘      └────────────┘    │  │
│                           │                              │  │
│           ┌───────────────┼───────────────┐             │  │
│           │               │               │             │  │
│       ┌───▼───┐       ┌───▼───┐       ┌───▼───┐        │  │
│       │Client │       │Client │       │Client │        │  │
│       └───────┘       └───────┘       └───────┘        │  │
│                                                          │  │
└─────────────────────────────────────────────────────────────┘

核心设计:
1. 连接管理:
   - 长连接(WebSocket)
   - 心跳检测
   - 断线重连

2. 消息存储:
   - 离线消息队列
   - 消息已读状态

3. 投递策略:
   - 在线推送
   - 离线存储 + 上线拉取
   - 推拉结合

4. 可靠性:
   - 消息 ACK
   - 重试机制
   - 去重

分布式 ID 生成

方案对比:
┌────────────┬─────────────┬─────────────┬─────────────┐
│   方案     │    优点     │    缺点     │   适用场景   │
├────────────┼─────────────┼─────────────┼─────────────┤
│ UUID       │ 简单、无依赖 │ 无序、太长  │ 低频、非主键 │
│ 自增 ID    │ 有序、简单  │ 单点、暴露量│ 单体应用    │
│ 号段模式   │ 数据库依赖低│ 需要预生成  │ 中等规模    │
│ Redis      │ 性能高     │ 依赖 Redis  │ 高并发     │
│ 雪花算法   │ 有序、高性能│ 时钟回拨    │ 分布式     │
└────────────┴─────────────┴─────────────┴─────────────┘

雪花算法:
┌─────────────────────────────────────────────────────────────┐
│ 0 │ 时间戳(41位)      │ 机器ID(10位)│ 序列号(12位)│
│   │ 约69年            │ 1024台机器  │ 4096/毫秒   │
└─────────────────────────────────────────────────────────────┘

时钟回拨处理:
1. 抛异常,等待时钟追上
2. 使用备用机器 ID
3. 使用 NTP 服务器同步

非功能需求清单

维度关注点常见方案
性能QPS、延迟缓存、异步、CDN
可用性SLA 99.9%?冗余、故障转移、限流
扩展性水平扩展无状态、分片
一致性强/最终一致分布式事务、消息队列
安全性认证、加密OAuth、HTTPS、WAF
可观测性日志、监控ELK、Prometheus
成本预算限制弹性伸缩、资源优化

基于 VitePress 构建