容量规划与架构容量模型:从QPS到资源预估
大约 8 分钟
前言
架构师需要回答的一个关键问题:
"这个系统最多能支持多少用户?"
"618大促来了,现有基础设施够吗?"
"扩容需要加多少台服务器?"
这些问题的答案不是拍脑门,而是基于容量规划模型的科学计算。
本文从业务指标出发,逐步推导出硬件资源需求,建立完整的架构容量模型。
一、容量规划的核心指标
1.1 流量指标层级
DAU (Daily Active Users) ← 日活跃用户数
└─ 每天有多少用户使用系统
└─ 关键指标,用于长期规划
PCU (Peak Concurrent Users) ← 峰值并发用户数
└─ 某个时刻最多有多少用户在线
└─ 关键指标,用于短期容量规划
QPS (Queries Per Second) ← 每秒查询数
└─ 最关键的技术指标
└─ 直接决定硬件规模
TPS (Transactions Per Second) ← 每秒事务数
└─ QPS的子集(某些请求才算一个事务)
Throughput ← 吞吐量
└─ 单位时间处理的数据量(MB/s)
1.2 从DAU推导QPS
假设:DAU = 100万
计算步骤:
1. 计算PCU(峰值并发用户)
假设:日均活跃时间分布
├─ 08:00-12:00: 40% 活跃
├─ 12:00-18:00: 60% 活跃(午间高峰)
├─ 18:00-23:00: 30% 活跃
└─ 其余时间: 5% 活跃
峰值时刻(18:00):
PCU = 100万 * 60% / (活跃时长 / 24小时)
= 100万 * 60% / 6小时
= 100万 * 0.1
= 10万 PCU
2. 计算平均QPS
假设:每个用户平均每秒发起 0.1 个请求
平均QPS = PCU * 0.1 = 10万 * 0.1 = 1万 QPS
3. 计算峰值QPS(突发流量)
峰值因子 = 1.5 - 2.0(用户行为聚合导致突发)
峰值QPS = 平均QPS * 峰值因子
= 1万 * 1.5 = 1.5万 QPS
4. 考虑多个业务线的QPS
总QPS = 订单QPS + 支付QPS + 库存QPS + ...
= 5000 + 3000 + 2000 + ...
= 15000 QPS
1.3 QPS to Latency
系统性能指标:
QPS: 1万 QPS
平均延迟:50ms
P99延迟:200ms
计算:
一个请求需要 50ms 才能完成
同时最多能处理 1000 / 50 * 1000 = 20 个并发请求
但如果QPS=10000,需要多少并发连接?
并发连接数 = QPS * 平均延迟(秒)
= 10000 * 0.05
= 500 个并发连接
二、单机容量模型
2.1 CPU瓶颈分析
单核CPU可以处理的QPS = 10000 (取决于业务逻辑复杂度)
常见应用的单核QPS:
├─ 静态文件服务(Nginx): 50000 QPS
├─ 简单API(Hello World): 10000 QPS
├─ 数据库查询(有缓存): 5000 QPS
├─ 复杂业务逻辑: 1000 QPS
└─ 机器学习推荐: 100 QPS
现代CPU配置:8核
单机QPS = 单核QPS * CPU核数 * 利用率
= 10000 * 8 * 0.7
= 56000 QPS
(不能100%利用,通常70%左右,留余量应对突发)
2.2 内存瓶颈分析
Java应用堆内存计算:
基础JVM: 512MB
├─ 启动时自动分配
业务对象: 100MB
├─ 例如:缓存1000个用户对象
├─ 每个对象100KB
└─ 1000 * 100KB = 100MB
连接池: 200MB
├─ 100个数据库连接
├─ 每个连接2MB (协议缓冲、事务日志等)
└─ 100 * 2MB = 200MB
框架库: 300MB
├─ Spring、Hibernate等
总计: 512 + 100 + 200 + 300 = 1112MB ≈ 2GB
推荐:
├─ 小型应用:2GB
├─ 中型应用:4-8GB
├─ 大型应用:16GB+
内存与QPS的关系:
增加内存 → 缓存更多数据 → 减少数据库查询 → QPS提升
例如:
2GB内存:缓存1000个对象,hit=70% → QPS=5000
8GB内存:缓存10000个对象,hit=90% → QPS=8000
2.3 网络IO瓶颈
网络带宽 = 1Gbps (1000Mbps)
应用场景分析:
场景1:API服务(JSON响应)
平均响应大小:10KB
最大吞吐:1000Mbps / (10KB * 8bits/byte)
= 1000Mbps / 80Kbps
= 12500 requests/sec = 12500 QPS
场景2:大文件下载(视频/图片)
平均文件大小:5MB
最大吞吐:1000Mbps / (5MB * 8)
= 1000Mbps / 40Mbps
= 25 requests/sec = 25 QPS(网络极限)
网络优化方案:
├─ CDN分发:减少跨域流量
├─ 压缩:gzip压缩减少60%数据量
├─ 升级带宽:10Gbps网卡
└─ 多线路:多ISP链接负载均衡
2.4 磁盘IO瓶颈
磁盘类型与IOPS(每秒操作次数):
SSD: 100000 IOPS
HDD: 1000 IOPS
数据库写入分析:
假设:每个写请求需要 3次磁盘操作
├─ 写入binlog(MySQL主从同步)
├─ 写入redo log(事务日志)
└─ 写入数据文件
磁盘限制的QPS:
SSD: 100000 / 3 ≈ 33000 write-QPS
HDD: 1000 / 3 ≈ 333 write-QPS
优化方案:
├─ 使用SSD: HDD → SSD, 提升100倍
├─ WAL优化: 批量写入 + 异步fsync
├─ 主从分离: 写向master, 读向slave
└─ 分库分表: 多个数据库并行处理
2.5 单机容量总结
假设应用:
├─ 平均QPS: 1000
├─ 峰值QPS: 2000
├─ 平均延迟: 50ms
├─ 需要持久化(数据库)
计算单机配置:
CPU:
需要QPS 2000 (峰值) / 10000 (单核能力) = 0.2个CPU
考虑突发和降级,选择 4核 CPU
内存:
业务缓存 + 连接池 + JVM开销
选择 8GB
磁盘:
写QPS 200 (估算) / 100000 (SSD能力) = 0.002
磁盘不是瓶颈,使用500GB SSD即可
网络:
QPS 2000 * 平均响应10KB = 20MB/s
千兆网卡 (125MB/s) 充足
单机成本:
├─ 服务器:¥3000-5000
├─ 带宽:¥500/月
└─ 数据库:¥5000/月(云数据库)
三、分布式容量模型
3.1 水平扩容
需求:QPS 100万
单机能力:
├─ QPS: 10000
├─ 成本: ¥10000/年
需要服务器数:
100万 / 10000 = 100 台
关键问题:
├─ 如何分散流量? → 负载均衡
├─ 如何避免单点? → 冗余设计
└─ 如何监控100台? → 自动化运维
架构:
┌──────────────┐
│ Load Balancer│
└──────────────┘
│
┌───┴───┬────┬────┬─────┐
▼ ▼ ▼ ▼ ▼
Srv1 Srv2 Srv3 ... Srv100
每个服务器 10000 QPS
100个服务器 = 100万 QPS
3.2 数据库容量规划
问题:100台应用服务器,但只能有1个数据库吗?
数据库瓶颈分析:
写QPS = 100万 * 10% = 10万 write/sec
读QPS = 100万 * 90% = 90万 read/sec
单台MySQL能力:
├─ 写:10000 write/sec
└─ 读:50000 read/sec
需要的数据库:
写:10万 / 10000 = 10台 master
读:90万 / 50000 = 18台 slave
但生产方案(主从复制):
├─ 1个Master(写)
├─ 3-5个Slave(读)
└─ 可以分库分表来扩展
分库分表策略:
├─ 按用户ID分库:100个库,每库 100万用户/100 = 1万用户
├─ 每个库1个Master + 2个Slave
└─ 总计:100个Master + 200个Slave = 300台数据库服务器
成本:太高!通常采用:
├─ 云数据库(RDS):自动分片和备份
└─ 年成本:100万 * ¥100/月 = ¥1.2亿
3.3 缓存容量规划
使用缓存减轻数据库压力:
假设:缓存hit rate = 90%
写QPS:10万 → 无法减少(必须写DB)
读QPS:90万 → 90% * 90万 = 81万 来自缓存
剩余:9万 来自DB
缓存需求:
├─ 缓存热数据(Top 20% 用户数据)
├─ 20% * 1000万用户 = 200万用户
├─ 每个用户对象 1KB
└─ 总内存:200万 * 1KB = 2GB
Redis容量规划:
├─ 单台Redis:30GB内存,可处理100K QPS
├─ 需要:2GB / 30GB = 0.1台(只需1台)
├─ 考虑主从备份和高可用:3台 (主+从+sentinel)
└─ 年成本:3 * ¥5000 = ¥15000
效果:
├─ 缓存前:DB 10万 write/sec + 90万 read/sec = 100万 QPS
├─ 缓存后:DB 10万 write/sec + 9万 read/sec = 19万 QPS
├─ 数据库需求从300台 → 20台(大幅节省)
└─ ROI极高
四、容量规划检查清单
4.1 计算方程式
QPS计算:
QPS = DAU * 日均活跃时长(小时) / 24 * 每用户请求数/秒 * 峰值因子
服务器数量:
Server_Count = Peak_QPS / Single_Server_QPS * Safety_Factor
例:Peak_QPS = 10万, Single_Server_QPS = 10000, Safety = 1.5
Server_Count = 100000 / 10000 * 1.5 = 15台
CPU核数:
Cores = Peak_QPS / QPS_Per_Core / CPU_Utilization
例:Peak_QPS = 10000, QPS_Per_Core = 1000, Utilization = 70%
Cores = 10000 / 1000 / 0.7 = 14核
内存大小:
Memory = Base_JVM + Cache_Size + Connection_Pool + Libraries
例:512MB + 1GB + 500MB + 500MB = 2.5GB → 选4GB或8GB
数据库:
DB_Write_Capacity = Write_QPS / Per_DB_Write_QPS
DB_Read_Capacity = Read_QPS / Per_DB_Read_QPS * (1 - Cache_Hit_Rate)
4.2 容量规划表
┌────────────┬──────────┬──────────┬──────────┬──────────┐
│ 业务规模 │ DAU │ Peak QPS │ 服务器数 │ 年成本 │
├────────────┼──────────┼──────────┼──────────┼──────────┤
│ 小型应用 │ 10万 │ 1000 │ 2 │ 10万 │
│ 中型应用 │ 100万 │ 10000 │ 20 │ 100万 │
│ 大型应用 │ 1000万 │ 100000 │ 200 │ 1000万 │
│ 超大规模 │ 1亿 │ 1000000 │ 2000 │ 1亿 │
└────────────┴──────────┴──────────┴──────────┴──────────┘
(仅计算应用层,不含数据库、缓存等)
五、容量监控与告警
5.1 关键指标监控
class CapacityMonitoring:
"""容量监控"""
def __init__(self):
self.thresholds = {
'cpu_utilization': 0.75, # CPU >75% 告警
'memory_utilization': 0.80, # 内存 >80% 告警
'disk_utilization': 0.85, # 磁盘 >85% 告警
'qps_growth': 0.1, # QPS周环比增长 >10% 告警
}
async def check_capacity(self):
"""定期检查容量"""
while True:
metrics = {
'cpu': self.get_cpu_utilization(), # 0-1
'memory': self.get_memory_utilization(),
'disk': self.get_disk_utilization(),
'current_qps': self.get_current_qps(),
'peak_qps_week_ago': self.get_peak_qps_week_ago(),
}
# QPS周环比增长告警
qps_growth = (metrics['current_qps'] - metrics['peak_qps_week_ago']) / metrics['peak_qps_week_ago']
if qps_growth > self.thresholds['qps_growth']:
await self.alert(f"QPS周环比增长 {qps_growth:.1%}, 需要评估是否扩容")
# CPU/内存/磁盘利用率告警
for metric_name, threshold in self.thresholds.items():
if metric_name in metrics:
if metrics[metric_name] > threshold:
await self.alert(f"{metric_name} 已达 {metrics[metric_name]:.1%}")
await asyncio.sleep(300) # 5分钟检查一次
5.2 扩容决策树
当前QPS = 8000, 单机容量 = 10000
┌─────────────────────────┐
│ QPS增长到8000 │
└────────────┬────────────┘
│
CPU利用率 ?
┌─────────┴─────────┐
<70% >70%
│ │
否 是
│ │
继续观察 立即规划扩容
│ │
监控后续增速 评估:
│ ├─ 垂直扩容(升级硬件)
│ ├─ 水平扩容(加服务器)
│ └─ 优化(改代码、加缓存)
│
若周环比 >15% 选择方案:
│ ├─ 加缓存最快(2-3天)
│ └─────────┐ ├─ 垂直扩容(1周)
│ │ └─ 水平扩容(2周)
└────────────┘
│
扩容执行
总结
容量规划是架构师的核心技能:
- 了解业务指标(DAU → QPS)
- 分析单机瓶颈(CPU/内存/网络/磁盘)
- 计算所需资源(服务器数、DB数、缓存大小)
- 建立监控告警(及时发现容量问题)
- 制定扩容方案(快速响应增长)
黄金法则:
- 容量规划总是低估增长(数据往往比预期快)
- 留足余量(70% CPU利用率,不是100%)
- 定期压测验证(模型 ≠ 现实)