Skip to main content

Command Palette

Search for a command to run...

System Design Interview Ch 2 粗略估算

Updated
7 min readView as Markdown
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 分鐘內)的最高每秒請求數用於容量預估與壓測設計

常見誤區

  1. ❌ 只看平均 QPS → 忽略尖峰期導致過載

  2. ❌ 不區分層級 → API 與 DB QPS 不等

  3. ❌ 忽略 Cache 命中率 → 實際 DB QPS 大幅下降

  4. ❌ 不看延遲分佈(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
  • 吞吐量、資料留存時間、延遲要求

  • 讀寫比、資料體積、可用性目標

列出假設

  • 使用者數量/活躍比例(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)

我們得出以下結論:

  • 記憶體很快,但磁碟很慢

  • 盡可能避免磁碟尋址

  • 簡單的壓縮演算法很快

  • 如果可能的話,在透過網際網路傳送資料前先壓縮

  • 資料中心通常位於不同地區,在它們之間傳送資料需要時間

這些延遲數字揭示了現代電腦系統的效能特性:

速度階層

  1. CPU 快取/記憶體:奈秒級別

  2. SSD 存取:微秒級別

  3. 網路通訊:毫秒級別

  4. 機械硬碟:毫秒級別(最慢)

🎯 設計原則

  • 記憶體優先:盡量將熱點資料保存在記憶體中

  • 避免磁碟 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)平均修復時間

提高可用率的兩大思路:

  1. 增加 MTBF → 系統更穩定、故障頻率下降

  2. 降低 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)

  1. Endpoint 級別

    • 每個 API 路徑(如 /login/orders/users/{id})都設定獨立的 SLI

    • 適合用於:不同 Endpoint 負責不同商業功能,對可用性要求差異大

  2. 服務(Service)級別

    • 把所有或一組關鍵 Endpoint 聚合起來,計算整體成功率

    • 適合用於:只關注「整個服務可用/不可用」,不細分各路徑

  3. 流量加權(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 要求到架構設計

  1. 收到 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 流程:

    1. 單元測試 → 2. 整合測試 → 3. 部署到 Canary / Staging → 4. 觀察 SLI 指標 → 5. 全量上線

3. 容錯 & 降級設計

  • Circuit Breaker(斷路器)

  • Bulkhead(隔艙模式)

  • Timeout、Retry、Fallback → 保護下游服務

4. 災難恢復

  • 訂定 RPO / RTO,落實冷備 / 熱備方案

  • 定期演練「主機房失效切換」(DR Drill)

4. 監控、告警與運維

  1. Dashboard

    • 實時展示 SLI(成功率、Latency、Error Budget)

    • 結合業務指標(流量、訂單量)預測壓力

  2. Alert

    • 分級告警:P1(系統不可用)、P2(延遲升高)、P3(資源飽和)

    • 設定告警門檻、告警頻率(避免告警風暴)

  3. 事件管理

    • PagerDuty / Opsgenie on‐call

    • Blameless Postmortem(無責任歸屬的事故分析)

More from this blog

Get Your Hands Dirty on Clean Architecture CH5 Use Case

書本連結 前言 會挑這本書看的人,應該都是關心自己負責專案的軟體架構的人。不只希望開發的軟體能滿足客戶的明確需求,也希望能滿足可維護性(maintainability)的隱性需求,以及自己對結構與美觀習慣的要求。 要能滿足上述這些要求很難,因為專案通常不會按照計畫進行。可能變因有 deadline,最後的 API 與承諾的不同,又或者我們的設計無法很好的貼合需求的變化所需。。因此完美的架構只有在一

Jul 2, 20264 min read26
Get Your Hands Dirty on Clean Architecture CH5 Use Case

Claude Code 監控秘錄:OpenTelemetry(OTel/OTLP)實戰指南

稟告主公:此乃司馬懿進呈之兵書,詳解如何以 OpenTelemetry 陣法,令臥龍神算之一舉一動盡在掌握,知糧草消耗、察兵器效能、辨戰報異常,使主公運籌帷幄於大帳之中。 為何需要斥候情報? 司馬懿稟告主公: 臥龍神算(Claude Code)乃當世利器,然若無斥候回報,主公便如蒙眼行軍——兵器耗損幾何、糧草消費幾許、哪路斥候出了差錯,一概不知。臣以為,此乃兵家大忌。 無情報之弊,有四: 軍

Feb 19, 202610 min read241
Claude Code 監控秘錄:OpenTelemetry(OTel/OTLP)實戰指南
M

MicroFIRE

74 posts