在云时代,TPS、CPU、内存、IOPS的估算仍然有必要吗?

每当谈到性能和容量估算时,总会出现类似的问题。

  • “TPS应该设定为多少?”
  • “需要多少个CPU?”
  • “需要多少内存?”
  • “IOPS如何计算?”
  • “要支持500个并发用户,需要多少台服务器?”

但在实际工作中,你会产生这样的想法:

反正计算了也会错,不是吗?

没错。大多数情况下都会出错。

特别是当服务尚未构建,或者不了解实际用户行为模式时,计算出的TPS、CPU、内存、IOPS和网络数值几乎都不准确。

那么,在云环境中,我们是否就不需要进行这些计算了呢?

  • “云有自动扩缩功能,是不是只要设计成可扩展的就行了?”
  • “反正计算会出错,是不是一开始就不用太纠结?”

我对这些问题的看法是:

精确的容量估算几乎是不可能的。

但容量估算本身并非毫无意义。

容量估算不是为了得出正确答案,而是将假设以数字形式展现,并创建可验证的初始设计的过程。

1. 容量估算为何经常出错?

容量估算出错的最大原因并非计算公式不足。

而是输入值不准确。

例如,假设有以下需求:

전체 사용자 3,000명
동시 접속자 500명
이 사용자를 처리할 수 있는 아키텍처 설계

表面上看,这似乎很明确。

但仅凭这些信息无法计算TPS。

因为“500个并发用户”实际意味着什么并不清楚。

可能是500个用户只是登录并查看屏幕的状态。

可能是500个用户每30秒点击一次按钮的状态。

可能是500个用户每1秒发送一次API请求的状态。

一个用户的业务请求在内部可能调用1个API,也可能调用5个API。

也就是说,仅凭并发用户数无法了解实际负载。

条件 实际负载
500人仅保持登录 TPS非常低
500人每30秒请求1次 约16.7 TPS
500人每10秒请求1次 约50 TPS
500人每1秒请求1次 约500 TPS
1个业务调用5个内部API 基于API最大可达2,500 RPS

因此,容量估算的第一步不是选择服务器规格。

而是将需求转换为更准确的负载模型。

2. 并发用户数与TPS不同

性能估算中最常见的误解是:

500个并发用户 = 500 TPS

不能这样看。

  • 并发用户数是特定时间点连接到系统的用户数量。
  • TPS是每秒处理的业务事务数量。
  • RPS是每秒API请求数量。

这三者是不同的。

전체 사용자 수: 서비스를 사용할 수 있는 전체 사용자 규모
동시 접속자 수: 특정 시점에 접속 중인 사용자 수
TPS: 초당 처리되는 업무 트랜잭션 수
RPS: 초당 API 요청 수

在性能建模中,我们经常参考利特尔法则来解释并发性、吞吐量和停留时间之间的关系。利特尔法则解释了系统中平均任务数L是到达率λ和平均停留时间W的乘积。即表示为L = λW。

在实际工作中,可以将其简化为如下形式:

업무 TPS ≒ 동시 사용자 수 / (평균 응답시간 + Think Time)

API RPS ≒ 업무 TPS × 업무 1건당 API 호출 수

DB QPS ≒ 업무 TPS × 업무 1건당 DB 쿼리 수

这里的Think Time是用户在进行下一个操作之前等待的时间。

例如,用户查看列表、阅读内容、然后点击下一个按钮所花费的时间就是Think Time。

如果忽略这个值,计算出的TPS会比实际情况高得多。

3. 在云中,是否可以不计算,只做成可扩展的?

一半对,一半错。

在云环境中,像以前那样精确计算需要购买多少台服务器的容量估算,其重要性已经降低。

利用Auto Scaling、托管数据库、负载均衡器、CDN、队列、无服务器等服务,可以更灵活地应对需求变化。

但这并不意味着不需要计算。

需要计算的原因如下:

초기 인프라 규모를 정하기 위해
Auto Scaling의 최소/최대 용량을 정하기 위해
비용 범위를 예측하기 위해
DB, Storage, Network 병목을 미리 찾기 위해
부하테스트 기준을 만들기 위해
요구사항을 검증 가능한 숫자로 바꾸기 위해

从AWS Well-Architected的性能效率角度来看,高效利用云资源以满足性能需求并保持其效率,也被视为一项重要原则。

此外,AWS将云负载测试描述为在现实条件下测量预期用户负载,并在类似生产环境的条件下分析指标的过程。这意味着不仅仅是计算,还需要在与实际相似的环境中施加负载并进行验证。

因此,云中的容量估算应如下看待:

정확한 예측: 거의 불가능
대략적인 초기 산정: 필요
확장 가능한 설계: 필수
부하테스트 검증: 필수
운영 지표 기반 보정: 필수

4. 3,000用户和500并发用户示例

现在我们举一个例子。

需求如下:

전체 사용자: 3,000명
피크 동시 접속자: 500명

在此基础上,我们添加以下假设:

사용자 1명은 평균 10초에 한 번 주요 업무 요청을 수행
업무 1건은 내부 API 4개를 호출
업무 1건당 DB read 3회
업무 1건당 DB write 1회
평균 응답 크기 50KB
평균 요청 크기 5KB
피크 여유 계수 2배

那么,业务TPS可以这样计算:

업무 TPS = 500명 / 10초 = 50 TPS

如果一个业务内部调用4个API,那么API RPS如下:

API RPS = 50 TPS × 4 = 200 RPS

反映2倍的峰值余量系数后如下:

피크 API RPS = 200 × 2 = 400 RPS

数据库请求量可以这样计算:

DB read/sec = 50 TPS × 3 × 2 = 300 read/sec
DB write/sec = 50 TPS × 1 × 2 = 100 write/sec

网络出站流量可以这样计算:

Network Out = 400 RPS × 50KB
            = 20,000KB/s
            ≒ 20MB/s
            ≒ 160Mbps

这个值不是正确答案。

但作为设计的起点,它具有足够的意义。

现在,我们不再模糊地说“请支持500个并发用户”,而是可以这样说:

피크 기준 약 400 API RPS를 처리할 수 있어야 한다.
DB는 초당 read 300회, write 100회 수준을 초기 기준으로 본다.
응답 트래픽은 약 160Mbps 이상을 예상한다.
이 값은 부하테스트를 통해 검증하고 보정한다.

这样转换是容量估算的核心。

5. CPU如何估算?

CPU的估算很难仅凭计算公式精确得出。

它会根据应用程序语言、框架、查询方式、是否使用缓存、JSON序列化成本、加密、是否调用外部API等因素而大相径庭。

因此,CPU通常按以下方式估算:

1. 기준 인스턴스 또는 컨테이너를 정한다.
2. 부하테스트를 통해 해당 단위가 처리 가능한 RPS를 측정한다.
3. 목표 RPS를 단위 처리량으로 나눈다.
4. 장애, 배포, 피크 여유를 반영한다.

例如,假设测试结果如下:

2 vCPU / 4GB 컨테이너 1개
CPU 사용률 60~70%
p95 응답시간 300ms 이하
에러율 1% 이하
처리량 100 RPS

如果前面计算的峰值API RPS是400 RPS,那么简单计算如下:

필요 컨테이너 수 = 400 RPS / 100 RPS = 4개

但在实际工作中,不会正好是4个。

会考虑到故障情况、部署期间容量减少、特定可用区故障、流量激增等因素,留有余量。

평상시 최소 용량: 2~3개
피크 예상 용량: 4~6개
Auto Scaling 최대 용량: 8~10개

这样设计更符合实际。

6. 内存如何估算?

内存会根据应用程序结构而大相径庭。

大致的计算公式如下:

필요 Memory =
OS/Runtime 기본 사용량
+ 애플리케이션 Heap
+ 커넥션/세션당 메모리
+ 내부 캐시
+ 버퍼 20~30%

但在云架构中,有一个更重要的原则:

应用程序服务器应尽可能设计为无状态。

将会话存储在服务器内存中会使增加服务器数量变得困难。

因为特定用户的会话会绑定到特定服务器。

因此,最好通过以下方式分离会话信息:

JWT
Redis / ElastiCache
Database Session Store
외부 인증 서비스

这样,API服务器可以随时增减。

要在云中构建可扩展的结构,应在估算内存之前检查状态管理方式。

7. IOPS如何估算?

IOPS的估算尤其需要谨慎。

数据库查询次数与磁盘IOPS并非1:1对应。

一次SELECT操作并不总是意味着一次磁盘读取。

如果数据已加载到缓存中,可能不会读取磁盘;反之,由于连接、排序、临时表、索引访问等原因,可能会产生更多的I/O。

写入也是如此。

一次INSERT或UPDATE操作并非简单地导致一次IOPS。

它还会受到事务日志、索引更新、复制、检查点、存储层操作等的影响。

因此,初始IOPS估算最好按以下级别进行:

DB read/sec = 업무 TPS × 업무당 read 쿼리 수 × 피크 계수
DB write/sec = 업무 TPS × 업무당 write 쿼리 수 × 피크 계수
예상 IOPS = read/write 요청량 × 보정계수

例如,在前面的例子中如下:

업무 TPS: 50
피크 계수: 2
업무당 read: 3
업무당 write: 1

read 요청 = 50 × 2 × 3 = 300/sec
write 요청 = 50 × 2 × 1 = 100/sec

这个值是选择数据库实例和存储的初始标准。

最终判断必须通过数据库监控和负载测试进行。

需要检查的指标如下:

DB CPU 사용률
DB Connection 수
Read IOPS / Write IOPS
Disk Queue Depth
Buffer Cache Hit Ratio
Slow Query
Lock Wait
Replication Lag
p95 / p99 Query Latency

数据库不像应用程序服务器那样可以无限轻松地扩展。

因此,在云设计中,数据库瓶颈必须单独处理。

8. 网络如何估算?

网络的计算相对简单。

Network Out = RPS × 평균 응답 크기
Network In = RPS × 평균 요청 크기

例如,假设如下:

피크 API RPS: 400
평균 응답 크기: 50KB
평균 요청 크기: 5KB

那么可以这样计算:

Network Out = 400 × 50KB = 20,000KB/s ≒ 160Mbps
Network In = 400 × 5KB = 2,000KB/s ≒ 16Mbps

但是,这里有一些注意事项。

如果静态文件、图片、视频、附件下载通过API服务器传出,网络估算会发生很大变化。

因此,在典型的云架构中,静态资源会按以下方式分离:

정적 파일: S3 또는 Object Storage
전송 최적화: CloudFront / CDN
동적 요청: API Server

这样,API服务器可以专注于业务逻辑处理,而大容量流量则由CDN和对象存储负责。

9. 自动扩缩不能替代计算

有人可能会认为有了自动扩缩就不需要计算了。

但自动扩缩也需要标准。

AWS EC2 Auto Scaling的目标跟踪策略根据CPU利用率、网络、ALB每目标请求计数、自定义CloudWatch指标等目标指标来调整容量。AWS文档解释说,目标跟踪会根据目标指标值自动调整Auto Scaling组的容量。

也就是说,要设置自动扩缩,需要回答以下问题:

CPU 60%를 목표로 할 것인가?
ALB RequestCountPerTarget 100을 목표로 할 것인가?
p95 응답시간을 Custom Metric으로 쓸 것인가?
최소 인스턴스 수는 몇 개인가?
최대 인스턴스 수는 몇 개인가?
Scale-out은 얼마나 빠르게 할 것인가?
Scale-in은 얼마나 보수적으로 할 것인가?

最终,自动扩缩也需要容量估算的结果。

但有所不同。

旧式的容量估算更接近于“多少台服务器就足够了?”

云式的容量估算更接近于“根据什么标准进行扩展,扩展多少,以及在哪个点会出现瓶颈?”

10. 3,000用户 / 500并发用户基准推荐架构

如果需求是“3,000用户,500并发用户”,可以提出以下结构作为基本架构:

사용자
  ↓
Route 53 / DNS
  ↓
CloudFront + WAF
  ↓
Application Load Balancer
  ↓
ECS / EKS / Auto Scaling Group
  ↓
Stateless API Server
  ↓
Redis / ElastiCache
  ↓
RDS / Aurora Multi-AZ
  ↓
S3 / Object Storage

如果需要异步处理的业务,则添加以下配置:

API Server
  ↓
SQS / EventBridge / Kafka
  ↓
Worker Auto Scaling
  ↓
Database / External API

核心是不要将所有请求都推入同步处理。

例如,以下任务是异步化的对象:

이메일 발송
문자 발송
대용량 리포트 생성
이미지 처리
외부 API 연동
결제 후 후속 처리
로그 분석
AI 추론 작업

将这些任务基于队列进行分离,可以减少用户感受到的响应时间,并更稳定地吸收瞬时流量。

Google Cloud Well-Architected Framework也从安全性、效率、弹性、高性能、成本优化和可持续性等角度提供了设计和运营云拓扑的建议。最终,云架构不仅要考虑性能,还要兼顾成本、运营和稳定性。

11. 如何处理才好?

如果收到关于“计算TPS、CPU、内存、IOPS、网络,设计一个能处理3,000用户和500并发用户的架构”的讲座邀请,单纯使用计算公式是危险的。

在实际工作中,以下流程是比较好的:

1. 사용자 수와 동시 접속자의 차이
2. 동시 접속자를 TPS/RPS로 변환하는 방법
3. 업무 시나리오 정의
4. API 호출 수, DB 쿼리 수, 응답 크기 추정
5. CPU, Memory, IOPS, Network 초기 산정
6. 확장 가능한 클라우드 아키텍처 설계
7. Auto Scaling 정책 설계
8. 부하테스트 수행
9. 병목 분석
10. 비용과 안정성 균형 조정

必须强调的信息是:

容量估算不是一个寻找正确答案的问题。

它是一个建立假设、用数字表达、通过负载测试验证、并用运营指标修正的过程。

特别是“500个并发用户”这个需求,需要分解成以下问题:

500명은 로그인 세션 기준인가, 활성 사용자 기준인가?
사용자는 몇 초마다 요청하는가?
업무 1건은 API 몇 개를 호출하는가?
API 1건은 DB 쿼리를 몇 번 발생시키는가?
평균 응답 크기는 얼마인가?
p95 응답시간 목표는 얼마인가?
장애 상황에서도 500명을 처리해야 하는가?
피크는 5분인가, 1시간인가, 하루 종일인가?
정적 파일 트래픽은 API 서버가 처리하는가, CDN이 처리하는가?

如果不回答这些问题就直接计算CPU、内存、IOPS,那么大多数数字都会变得毫无意义。

12. 简单的容量估算代码

在讲座或实践中,最好制作并展示一个如下的简单计算器:

import math

def estimate_capacity(
    concurrent_users: int,
    think_time_sec: float,
    avg_response_time_sec: float,
    api_calls_per_business_tx: int,
    peak_factor: float,
    avg_response_kb: float,
    avg_request_kb: float,
    db_reads_per_tx: int,
    db_writes_per_tx: int,
    rps_per_app_instance_at_target: int,
    ha_buffer: float = 1.25,
):
    # 业务TPS计算
    # 包括用户发出请求后等待下一个请求的时间
    business_tps = concurrent_users / (think_time_sec + avg_response_time_sec)

    # API RPS计算
    api_rps = business_tps * api_calls_per_business_tx

    # 反映峰值系数
    peak_api_rps = api_rps * peak_factor

    # 数据库请求量计算
    db_read_per_sec = business_tps * db_reads_per_tx * peak_factor
    db_write_per_sec = business_tps * db_writes_per_tx * peak_factor

    # 网络带宽计算
    network_out_mbps = peak_api_rps * avg_response_kb * 8 / 1024
    network_in_mbps = peak_api_rps * avg_request_kb * 8 / 1024

    # 应用实例数计算
    required_instances = math.ceil(
        (peak_api_rps / rps_per_app_instance_at_target) * ha_buffer
    )

    return {
        "business_tps": round(business_tps, 2),
        "api_rps": round(api_rps, 2),
        "peak_api_rps": round(peak_api_rps, 2),
        "db_read_per_sec": round(db_read_per_sec, 2),
        "db_write_per_sec": round(db_write_per_sec, 2),
        "network_out_mbps": round(network_out_mbps, 2),
        "network_in_mbps": round(network_in_mbps, 2),
        "required_app_instances": required_instances,
    }

result = estimate_capacity(
    concurrent_users=500,
    think_time_sec=10,
    avg_response_time_sec=0.5,
    api_calls_per_business_tx=4,
    peak_factor=2,
    avg_response_kb=50,
    avg_request_kb=5,
    db_reads_per_tx=3,
    db_writes_per_tx=1,
    rps_per_app_instance_at_target=100,
)

for key, value in result.items():
    print(f"{key}: {value}")

预期结果与以下类似:

business_tps: 47.62
api_rps: 190.48
peak_api_rps: 380.95
db_read_per_sec: 285.71
db_write_per_sec: 95.24
network_out_mbps: 148.81
network_in_mbps: 14.88
required_app_instances: 5

看到这个结果,不应该判断“服务器肯定5台就够了”。

这个值是基于初始假设的起点。

在实际讲座中,最好以这个值为基准进行负载测试,并观察以下指标:

CPUUtilization
MemoryUtilization
RequestCount
TargetResponseTime
HTTPCode_ELB_5XX
HTTPCode_Target_5XX
DB CPU
DB Connections
ReadIOPS / WriteIOPS
p95 / p99 Latency
Queue Depth

结论:计算会出错。但仍然需要计算。

性能和容量估算大多会出错。

特别是,在不了解实际用户行为、数据大小、查询模式和代码性能的情况下计算出的值,不可能是正确答案。

但这并不意味着容量估算毫无用处。

云时代的容量估算并非精确匹配服务器数量的工作。

它是一个将假设以数字形式展现、创建架构设计基线、并通过负载测试和运营指标进行验证的过程。

总结如下:

계산만 믿으면 위험하다.
계산 없이 설계하면 더 위험하다.
클라우드에서는 확장 가능하게 설계해야 한다.
하지만 확장 기준을 만들기 위해 초기 산정은 반드시 필요하다.
최종 답은 계산식이 아니라 부하테스트와 운영 데이터가 준다.

因此,在设计“处理3,000用户和500并发用户的架构”时,以下方法是最现实的:

1. 동시 접속자를 TPS/RPS로 변환한다.
2. 업무 시나리오와 API 호출 구조를 정의한다.
3. CPU, Memory, IOPS, Network를 초기 산정한다.
4. Stateless, CDN, Cache, Queue, Auto Scaling 기반으로 설계한다.
5. 부하테스트로 검증한다.
6. 운영 지표를 보고 보정한다.

目标不是精确无误。

目标是在假设会出错的前提下,快速验证并安全扩展的结构。


Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注