粗略估算 · 系统设计
一个有一百万用户的应用需要多少台服务器?
课程目录为什么需要它
每一次系统设计都从规模开始。一个数据库还是五十个?数据是几个 GB 还是几百 TB?还不存在的系统没法测量,但一次快速的估算通常能把数量级估对,这就足以排除那些根本行不通的设计。面试也会考这个。
直觉理解
从已知推到所需,每次只做一步乘除:
- 每天请求数 = 日活用户 × 每人请求数
- 平均每秒 = 每天请求数 / 86,400(一天的秒数)
- 峰值每秒 = 平均值 × 峰值系数。流量不是一条直线;如果有类似流量的实测系数就用它,没有就自己选一个,并把它写下来
- 服务器数 = 峰值 / 一台服务器能扛的量,向上取整。「一台服务器能扛的量」来自压力测试,绝不能靠猜
- 再加一台备用,这样坏一台也扛得住(常写作 N + 1)
存储也是同样的算法:每天的条数 × 每条大小 × 保留天数 × 副本数。
数字保持取整。86,400 接近 100,000,所以每天一百万次请求,大约就是每秒 10 次。重点是又快又大致准确,并且把你的假设写出来,让别人能纠正。
定义
QPS
Queries (requests) per second: the usual unit of load.每秒查询(请求)数:衡量负载的常用单位。
峰值系数
How much busier the busiest time is than the average.最忙的时候比平均水平忙多少倍。
N + 1
Running one more server than the load needs, so one failure doesn't overload the rest.比负载需要的多运行一台服务器,这样坏一台也不会压垮其他的。
示例
从用户数到服务器数
动手试试一百万日活用户,每人 20 次请求,峰值系数 3,压力测试显示一台服务器每秒能扛 200 次。
import math
daily = 1_000_000 * 20
average = daily / 86_400
peak = average * 3
servers = math.ceil(peak / 200) + 1
print(round(average), round(peak), servers)输出
231 694 5
逐步执行
- L3每天两千万次请求。下划线只是让大数字更好读。
- L4平均每秒约 231 次。
- L5最忙的时候每秒约 694 次。
- L6694 / 200 = 3.47 → 4 台,再加 1 台备用。
5
照片的存储
动手试试每天两百万张照片,每张 2 MB,保存一年,存 3 份。
photos_per_day = 2_000_000
mb_each = 2
days = 365
copies = 3
tb = photos_per_day * mb_each * days * copies / 1_000_000
print(tb, "TB")输出
4380.0 TB
逐步执行
- L5MB → TB 是除以一百万(按十进制单位)。
- L6几千 TB:一台数据库服务器肯定不行,需要对象存储。
常见错误
按平均值设计
流量有高峰。按平均值配置的系统,每天晚上都会扛不住。
凭猜测估服务器能力
「一台服务器每秒能扛一万次」完全取决于每次请求要做多少工作。对你自己的服务做压力测试。
忘了副本和增长
备份、副本和明年的增长,常常让存储需求翻好几倍。
小测验
1. 这段代码会输出什么?
per_day = 8_640_000
print(per_day / 86_400)查看答案
答案:A
8,640,000 / 86,400 = 每秒 100 次。
2. 为什么在峰值所需之外再多加一台服务器?
查看答案
答案:A
N + 1:任意坏掉一台,剩下的容量也够用。
动手练习
3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。
- 预测输出取整的数
准确写出它打印的内容。
- 改需求每一份都要算
storage_tb忘了每张照片要存copies份。修正它。 - 从零写要几台服务器?
写一个
servers_needed(daily_users, per_user, peak_factor, per_server):- 峰值每秒 = daily_users × per_user / 86,400 × peak_factor
- 负载所需的服务器 = 峰值 / per_server,向上取整,但至少 1 台
- 返回这个数再加 1 台备用
servers_needed(1_000_000, 20, 3, 200) # 5
本课术语
| 术语 | 中文 | 英文定义 |
|---|---|---|
| QPS | 每秒请求数 | Requests per second. |
| Peak factor | 峰值系数 | How much busier the peak is than the average. |
| N + 1 | N + 1 冗余 | One spare server beyond what the load needs. |