System Design Interview Ch 2 粗略估算

在系統設計面試關卡中,經常會要求面試者粗略估算來評估系統容量或效能需求。估算的目的都是為了系統的可擴展性(Scalability)。
back-of-the-envelope calculations are estimates you create using a combination of thought experiments and common performance numbers to get a good feel for which designs will meet your requirements
粗略估算是你結合思想實驗和常見效能數據所創建的估算,用來了解哪些設計能滿足你的需求
粗略估算不是要算得非常精確,而是在面試限時內,快速判斷系統容量、吞吐量、儲存與成本,並據此選擇合理架構。
🎯 系統設計中的效能瓶頸與粗略估算思維
在設計分散式系統時,首先要辨識出整個鏈路中最關鍵的效能瓶頸。
如果系統的服務鏈中存在「主要吃硬碟的組件」──例如資料庫、搜尋引擎或訊息佇列──那麼整體**吞吐量(Throughput)**的上限,往往會由這類 I/O 密集服務所決定。
因此,第一步應該是根據實際業務場景,先對這些關鍵服務進行簡單的 benchmark 測試,例如測出資料庫在典型查詢下的 QPS(Queries Per Second)上限。
一旦掌握這個數據,其他依賴該資料庫的上層服務(API、應用層、快取層等)就能以此為基準,推算整體的流量能力與系統擴展需求。
峰值(Peak QPS)與平均(Average QPS)
在設計系統時,我們不只關心平均值,更要關心「尖峰時刻」的請求量:
| 指標 | 定義 | 用途 |
| 平均 QPS | 一天總請求 ÷ 86400 秒 | 評估整體負載 |
| 峰值 QPS(Peak QPS) | 峰值期間(例如 5 分鐘內)的最高每秒請求數 | 用於容量預估與壓測設計 |
常見誤區
❌ 只看平均 QPS → 忽略尖峰期導致過載
❌ 不區分層級 → API 與 DB QPS 不等
❌ 忽略 Cache 命中率 → 實際 DB QPS 大幅下降
❌ 不看延遲分佈(P95/P99) → 高延遲請求導致併發壅塞
用 QPS 做容量預估
若單台伺服器可承受 5,000 QPS,
服務預估峰值為 25,000 QPS,
則需要:伺服器台數 = 峰值 QPS ÷ 每台 QPS = 25,000 ÷ 5,000 = 5 台
加上冗餘與健康檢查,通常會部署 N+1 或 N+2 架構:
→ 最終部署 6~7 台。
步驟
*澄清需求
QPS(Queries Per Second): 每秒完成的請求數(Requests / second) = 總請求數 ÷ 總時間(秒)
- 一個 API 伺服器在 10 秒內處理完了 50,000 次請求
→ QPS = 50,000 ÷ 10 = 5,000 QPS
- 一個 API 伺服器在 10 秒內處理完了 50,000 次請求
吞吐量、資料留存時間、延遲要求
讀寫比、資料體積、可用性目標
列出假設
使用者數量/活躍比例(DAU/MAU)
平均單請求/單筆資料大小
工作負載分佈(讀多寫少、峰值因子)
套用常見性能數字
Latency Numbers
單機機器能承受的 QPS(HTTP 伺服器、資料庫)
網路頻寬與 I/O 吞吐
計算 & Sanity Check
計算出 QPS、頻寬需求、每日/每年儲存量
把結果拿回「常識」比對:
每秒幾千 QPS 需幾台 Web 伺服器?
幾 TB 資料/天要多少硬碟?
形成結論與權衡
是否需要 Cache、分片、CDN、流量削峰…
預估硬體/雲端成本級別
每個系統工程師都應該知道的Delay數字
透過[Latency Numbers Every Programmer Should Know網站](https://colin-scott.github.io/personal_website/research/interactive_latency.html)
我們得出以下結論:
記憶體很快,但磁碟很慢
盡可能避免磁碟尋址
簡單的壓縮演算法很快
如果可能的話,在透過網際網路傳送資料前先壓縮
資料中心通常位於不同地區,在它們之間傳送資料需要時間
這些延遲數字揭示了現代電腦系統的效能特性:
⚡ 速度階層
CPU 快取/記憶體:奈秒級別
SSD 存取:微秒級別
網路通訊:毫秒級別
機械硬碟:毫秒級別(最慢)
🎯 設計原則
記憶體優先:盡量將熱點資料保存在記憶體中
避免磁碟 I/O:特別是隨機存取,或者將 I/O 操作批次化
善用壓縮:網路傳輸前壓縮資料
就近部署:減少跨地區的資料傳輸
這些基準數字是系統設計決策的重要依據,幫助我們識別效能瓶頸並選擇合適的架構策略。
範例:估算 Twitter 的 QPS 和儲存需求
請注意以下數字僅用於此練習,並非 Twitter 的真實數據。
假設條件:
3 億月活躍用戶
50% 的用戶(1.5億)每天使用 Twitter
用戶平均每天發布 2 則推文(3億篇推文)
10% 的推文包含媒體
資料儲存 5 年
估算:
QPS 估算:
日活躍用戶(DAU)= 3 億 × 50% = 1.5 億
推文 QPS = 1.5 億 × 2 則推文 ÷ 24 小時 ÷ 3600 秒 ≈ 3 500 qps
尖峰 QPS ≈ 2× 平均 = 7 000 qps
媒體儲存量估算:
平均推文大小:
tweet_id:64 bytes
文字:140 bytes
媒體:1 MB
推文文本:3e8 × 200 bytes ≈ 60 GB/天
媒體儲存:1.5 億 × 2 × 10% × 1 MB = 30 TB/天
5 年媒體儲存:30 TB × 365 × 5 = ~55 PB
Sanity Check
7 000 qps → 假設一台 Nginx + App 能承 5 000 qps → 2–3 台即可
55 PB → 若單機硬碟 20 TB → 約 3 000 顆分散式儲存
📊 常見的粗略估算問題
QPS、Peak QPS、儲存、Cache 機制、伺服器數量等。準備面試時可以練習這些計算。
高可用(High Availability)
高可用性是指系統能夠在理想的長時間內持續運作的能力。高可用性以百分比來衡量,100% 表示服務的停機時間為 0。大多數服務的可用性介於 99% 到 100% 之間。
**服務等級協議(SLA)**是服務提供商常用的術語。這是你(服務提供商)與客戶之間的協議,正式定義了你的服務將提供的正常運行時間等級。雲端服務提供商 Amazon [4]、Google [5] 和 Microsoft [6] 將他們的 SLA 設定在 99.9% 或以上。正常運行時間傳統上以「幾個 9」來衡量。9 的數量越多越好。9 的數量與預期的系統停機時間相關。
可用性等級對照
99% = 每年 3.65 天停機時間
99.9% = 每年 8.76 小時停機時間
99.99% = 每年 52.56 分鐘停機時間
99.999% = 每年 5.26 分鐘停機時間
**高可用性(High Availability, HA)**不只是追求「幾個九」的可用率,更是一整套在架構、運維和測試上保障服務不中斷的具體措施。
可用率計算公式
可用性計算的複雜性
基礎公式:
可用性 = MTBF / (MTBF + MTTR)
MTBF(Mean Time Between Failures)平均故障間隔
MTTR(Mean Time To Repair)平均修復時間
提高可用率的兩大思路:
增加 MTBF → 系統更穩定、故障頻率下降
降低 MTTR → 快速偵測、快速恢復
可用性 vs. 可靠性 vs. 耐久性
Availability(可用性):系統可「對外提供服務」的時間比例。
Reliability(可靠性):系統在指定時間內正確執行功能的概率。
Durability(耐久性):資料不遺失的程度(一般用在 Storage/Backup)
在 SLA 條款中若同時談「資料遺失賠償」,通常就是在講耐久性(Durability)。
實際案例對比:
| 場景 | 可用性 | 可靠性 | 耐久性 |
| 系統回應但資料錯誤 | ✅ 高 | ❌ 低 | ✅ 高 |
| 系統離線但資料完整 | ❌ 低 | ❌ 低 | ✅ 高 |
| 系統正常但資料遺失 | ✅ 高 | ❌ 低 | ❌ 低 |
| 理想狀態 | ✅ 高 | ✅ 高 | ✅ 高 |
關鍵指標:SLI / SLO / SLA
SLI (Service Level Indicator)
用於衡量系統健康度的指標,如「成功響應率」「99% 響應時間 ≤ 500 ms」等。SLO (Service Level Objective)
你對 SLI 設定的目標值。例如「每月成功響應率 ≥ 99.9%」。SLA (Service Level Agreement)
對客戶承諾的可用率(通常 ≥ 99.9%),並與未達標時的賠償機制綁定。
大型系統的現實挑戰:
串聯系統(Serial)
總可用性 = A₁ × A₂ × A₃ × ... × Aₙ
3個99.9%的服務串聯 = 99.7%
10個99.9%的服務串聯 = 99.0%
並聯系統(Parallel)
總不可用性 = (1-A₁) × (1-A₂) × ... × (1-Aₙ)
總可用性 = 1 - 總不可用性
- 2個99.9%的服務並聯 = 99.9999%
混合架構計算範例
Web層:2台並聯 (99.9% each) → 99.9999%
App層:3台並聯 (99.5% each) → 99.9875%
DB層:主從架構 (99.95%) → 99.95%
總可用性 = 99.9999% × 99.9875% × 99.95% ≈ 99.937%
一個大型服務往往包含多個 API Endpoint,要衡量「可用性」時,就要先明確定義你的 SLI(Service Level Indicator)和 SLO(Service Level Objective)針對哪個粒度:
可用性粒度(Granularity)
Endpoint 級別
每個 API 路徑(如
/login、/orders、/users/{id})都設定獨立的 SLI適合用於:不同 Endpoint 負責不同商業功能,對可用性要求差異大
服務(Service)級別
把所有或一組關鍵 Endpoint 聚合起來,計算整體成功率
適合用於:只關注「整個服務可用/不可用」,不細分各路徑
流量加權(Weighted)
根據流量大小或業務重要性,給不同 Endpoint 不同權重
例如:
/checkout佔總流量 20%,/search佔 50%,按流量加權後算出「加權可用率」
假設我們把 /login、/checkout、/search 三個 Endpoint 聚合成「電子商務服務」:
SLI:
successful_requests = 請求數中返回 2xx 的次數
total_requests = 所有到達三個 Endpoint 的請求
availability = successful_requests / total_requests
SLO:
每分鐘可用率 ≥ 99.9%
429 回應佔比上限 ≤ 1%。429 (Too Many Requests):屬於「流量保護/限流」,有時不算系統故障,但使用者無法完成操作,可視為可用性下降
SLA:
- 客戶承諾月度可用率 ≥ 99.9%,若低於則賠償
從 SLO 要求到架構設計
收到 SLO / SLA 要求 → 定義 SLIs
與 SRE / 架構師一起確認:
• 哪些 Endpoint、哪些指標要算進可用率?
• Time window(1 min / 5 min / 30 days rolling)
• 流量是否加權?範例:
SLO:
• 成功回應率 ≥ 99.9%(2xx)
• p99 Latency ≤ 500 ms
• 429 限流率 ≤ 1%
SLI 設計的層次化思維
業務層 SLI(Business-Level SLI)
# 電商系統範例
business_sli:
order_success_rate:
definition: "成功完成訂單 / 嘗試下單次數"
target: "> 99.5%"
payment_success_rate:
definition: "支付成功 / 支付嘗試次數"
target: "> 99.9%"
search_relevance:
definition: "用戶點擊前3個搜尋結果的比例"
target: "> 85%"
系統層 SLI(System-Level SLI)
system_sli:
api_availability:
definition: "2xx回應 / 總請求數"
measurement_window: "1分鐘"
target: "> 99.9%"
latency_p99:
definition: "99%請求的回應時間"
target: "< 500ms"
error_rate:
definition: "5xx錯誤 / 總請求數"
target: "< 0.1%"
基礎設施層 SLI(Infrastructure-Level SLI)
infrastructure_sli:
cpu_utilization:
target: "< 70% (sustained)"
memory_utilization:
target: "< 80%"
disk_io_wait:
target: "< 10%"
複雜系統的 SLO 分層設計
金字塔式 SLO 架構
┌─────────────────────────────────────┐
│ Business SLO (99.5%) │ ← 對客戶承諾
├─────────────────────────────────────┤
│ Service SLO (99.7%) │ ← 內部目標
├─────────────────────────────────────┤
│ Component SLO (99.9%) │ ← 元件目標
├─────────────────────────────────────┤
│ Infrastructure SLO (99.95%) │ ← 基礎設施
└─────────────────────────────────────┘
實際案例:微服務電商系統
# 業務層 SLO
business_slo:
checkout_flow:
slo: "99.5% 成功率"
error_budget: "0.5% = 3.6小時/月"
# 服務層 SLO
service_slo:
user_service:
availability: "99.8%"
latency_p95: "< 200ms"
order_service:
availability: "99.9%"
latency_p95: "< 300ms"
payment_service:
availability: "99.95%" # 更嚴格,因為影響收入
latency_p95: "< 500ms"
# 基礎設施 SLO
infrastructure_slo:
kubernetes_cluster:
node_availability: "99.95%"
database:
availability: "99.99%"
replication_lag: "< 1s"
大型複雜系統的可用性架構設計
多層次冗餘設計
地理分散架構
global_architecture:
regions:
- name: "us-east-1"
role: "primary"
capacity: "60%"
- name: "us-west-2"
role: "secondary"
capacity: "40%"
- name: "eu-west-1"
role: "disaster_recovery"
capacity: "100% (cold standby)"
failover_strategy:
rto: "< 5 minutes" # Recovery Time Objective
rpo: "< 30 seconds" # Recovery Point Objective
服務網格容錯模式
service_mesh_patterns:
circuit_breaker:
failure_threshold: 50%
timeout: 30s
reset_timeout: 60s
retry_policy:
max_attempts: 3
backoff: "exponential"
base_delay: 100ms
max_delay: 10s
bulkhead:
thread_pools:
critical_operations: 20
normal_operations: 10
background_tasks: 5
資料層可用性設計
分散式資料庫策略
database_architecture:
primary_db:
type: "PostgreSQL"
availability: "99.95%"
backup_strategy:
- continuous_wal_archiving
- daily_full_backup
- cross_region_replication
read_replicas:
count: 3
distribution:
- same_az: 1
- different_az: 2
lag_threshold: "< 100ms"
cache_layers:
l1_cache: "Application Memory"
l2_cache: "Redis Cluster"
l3_cache: "CDN"
consistency_model:
writes: "strong_consistency"
reads: "eventual_consistency_acceptable"
資料分片與路由
# 資料分片策略範例
class ShardingStrategy:
def __init__(self):
self.shards = {
'shard_1': {'range': '0-999999', 'master': 'db1', 'replicas': ['db1r1', 'db1r2']},
'shard_2': {'range': '1000000-1999999', 'master': 'db2', 'replicas': ['db2r1', 'db2r2']},
'shard_3': {'range': '2000000-2999999', 'master': 'db3', 'replicas': ['db3r1', 'db3r2']}
}
def route_query(self, user_id):
shard_key = user_id % 3
return self.shards[f'shard_{shard_key + 1}']
def handle_shard_failure(self, failed_shard):
# 自動故障轉移到副本
replicas = self.shards[failed_shard]['replicas']
return replicas[0] # 提升第一個副本為主庫
2. 架構 & 技術選型
根據 SLIs/SLOs 把可用性拆解到各層面需要採取的措施:
| 層級 | 措施範例 |
| 基礎架構 | ■ 多可用區域(AZ)或 Region 部署 |
| ■ Anycast DNS / Global LB | |
| 計算層 | ■ Auto-Scaling + Health Check |
| ■ 多實例冗餘,避免單點故障 | |
| 資料儲存層 | ■ 多副本/分片(Replication / Sharding) |
| ■ 定期備份,異地災難備援 | |
| 網路 & 流量管理 | ■ Load Balancer + Rate Limiter |
| ■ CDN / Edge Cache | |
| ■ Circuit Breaker | |
| 運維 & 驗證 | ■ 監控 + Alert(Prometheus + Alertmanager) |
| ■ Chaos Engineering |
3. 實作步驟
1. 指標蒐集(Instrumentation)
在程式碼中埋點(metrics)
• 請求量、成功/失敗次數、延遲時間、限流次數…選擇收集與視覺化工具
• Prometheus + Grafana、Datadog、New Relic
2. 自動化部署
IaC(Infrastructure as Code):Terraform、CloudFormation
CI/CD 流程:
- 單元測試 → 2. 整合測試 → 3. 部署到 Canary / Staging → 4. 觀察 SLI 指標 → 5. 全量上線
3. 容錯 & 降級設計
Circuit Breaker(斷路器)
Bulkhead(隔艙模式)
Timeout、Retry、Fallback → 保護下游服務
4. 災難恢復
訂定 RPO / RTO,落實冷備 / 熱備方案
定期演練「主機房失效切換」(DR Drill)
4. 監控、告警與運維
Dashboard
實時展示 SLI(成功率、Latency、Error Budget)
結合業務指標(流量、訂單量)預測壓力
Alert
分級告警:P1(系統不可用)、P2(延遲升高)、P3(資源飽和)
設定告警門檻、告警頻率(避免告警風暴)
事件管理
PagerDuty / Opsgenie on‐call
Blameless Postmortem(無責任歸屬的事故分析)






