Chuyển đến nội dung chính

第 2 課:效能與可擴展性 - 垂直和水平擴展

區分效能和可擴展性。垂直擴展(縱向擴展)與水平擴展(橫向擴展)。無狀態與有狀態架構。何時選擇哪種擴充策略?粗略計算和基本容量規劃。

🏗️ 建築 — 第 2 課 第 2 課:效能與可擴充性 - 垂直和水平縮放

系統架構:從零到英雄

第 1 部分:系統設計基礎

亞洲開發網

簡介

當系統開始變慢時,您面臨兩個問題:

  • 效能: 如何讓系統對使用者來說更快?
  • **可擴展性:**系統如何服務更多的使用者?

這兩個概念相關但又不同。了解差異是有效系統設計的第一步。


1. 效能與可擴充性

1.1 定義

Performance Problem:   Hệ thống chậm cho 1 user
Scalability Problem:   Hệ thống nhanh cho 1 user, nhưng chậm khi nhiều users
特點效能可擴充性
測量者回應時間、吞吐量增加負載處理能力
範例API 在 50 毫秒內回傳從 100 → 100K RPS
解決方案最佳化程式碼、演算法新增資源,分配負載
何時修復總是優化當負載超過容量時

1.2 實際例子

Scenario: API lấy danh sách sản phẩm

Performance Issue:
  - 1 user request → 5 giây (do query N+1, không có index)
  - Fix: Tối ưu query, thêm database index → 50ms

Scalability Issue:
  - 1 user → 50ms ✓
  - 1000 users cùng lúc → 3 giây (server quá tải)
  - Fix: Thêm servers, caching, load balancer

2. 垂直縮放(Scale Up)

2.1 概念

垂直擴展是為了增加單一伺服器的能力:增加CPU、RAM、SSD、網路頻寬。

Trước:                          Sau:
┌──────────────┐               ┌──────────────────┐
│   Server     │               │     Server       │
│  4 CPU       │    Scale Up   │  32 CPU          │
│  8 GB RAM    │  ──────────►  │  128 GB RAM      │
│  256 GB SSD  │               │  2 TB NVMe SSD   │
└──────────────┘               └──────────────────┘

2.2 優點和缺點

優勢缺點
簡單,無需改程式碼有實體限制(硬體限制)
無網路延遲單點故障
簡單的數據一致性成本呈指數級增長
無需分散式協調升級時停機

2.3 垂直擴展成本(例如 AWS EC2)

t3.micro    (2 vCPU, 1GB):    ~$8/tháng
t3.xlarge   (4 vCPU, 16GB):   ~$120/tháng      (15x giá, 16x RAM)
r5.4xlarge  (16 vCPU, 128GB): ~$730/tháng      (91x giá, 128x RAM)
r5.24xlarge (96 vCPU, 768GB): ~$4,400/tháng    (550x giá, 768x RAM)

成本成長快於效能提升。這就是垂直縮放具有實際限制的原因。


3. 水平擴展(Scale Out)

3.1 概念

水平擴展正在添加更多伺服器來分擔負載。

Trước:                     Sau:
                          ┌──────────────┐
                          │  Load        │
                          │  Balancer    │
                          └──────┬───────┘
                      ┌──────────┼──────────┐
┌──────────┐         ┌──┴──┐  ┌──┴──┐  ┌──┴──┐
│  Server  │  ────►  │ S1  │  │ S2  │  │ S3  │
│  (1 máy) │         │     │  │     │  │     │
└──────────┘         └─────┘  └─────┘  └─────┘

3.2 優點和缺點

優勢缺點
幾乎無限的縮放更複雜
無單點故障需要負載平衡器
成本線性增加資料一致性挑戰
可按需擴充需要無狀態設計

3.3 橫向擴展成本

1  x t3.xlarge:  $120/tháng   → 1x capacity
4  x t3.xlarge:  $480/tháng   → ~4x capacity
10 x t3.xlarge:  $1,200/tháng → ~10x capacity

成本隨容量線性增加-比垂直擴展效率更高。


4. 無狀態與有狀態架構

4.1 為什麼它很重要?

為了使水平擴展發揮作用,伺服器必須是無狀態——不在伺服器上儲存使用者狀態。

4.2 有狀態伺服器(擴充的反模式)

┌──────────┐     Request 1     ┌──────────┐
│  User A  │ ──────────────►   │ Server 1 │  ← Session: {userId: A, cart: [...]}
└──────────┘                   └──────────┘

                Request 2
User A ──────────────────────► Server 2   ← Không có session của User A!
                                            → ERROR: "Please login again"

問題: 如果下一個請求轉到另一台伺服器,會話就會遺失。

4.3 無狀態伺服器(最佳實務)

┌──────────┐                    ┌──────────┐
│  User A  │  Request + Token   │ Server 1 │
└──────────┘ ──────────────►    └──────────┘ ──► Shared Session Store
                                                  (Redis / Database)
             Request + Token    ┌──────────┐        │
             ──────────────►    │ Server 2 │ ──────►│
                                └──────────┘

解決方案:將會話儲存到共用儲存(Redis、資料庫),伺服器僅處理邏輯。

4.4 處理狀態的方法

方法描述優點缺點
黏性會話LB將使用者傳送到同一台伺服器簡單伺服器故障=會話遺失
會話儲存(Redis)在 Redis 中儲存會話快速、可擴充新增元件
智威湯遜令牌代幣狀態無需伺服器儲存Token規模大,撤銷難
資料庫將會話保存在資料庫中堅持不懈比 Redis 慢

5. 容量規劃

5.1 程序

1. Xác định metrics hiện tại
   └─ QPS, storage, bandwidth

2. Dự đoán growth
   └─ User growth rate, feature expansion

3. Tính capacity cần thiết
   └─ Servers, storage, bandwidth

4. Thêm headroom (20-30%)
   └─ Buffer cho traffic spike

5.2 範例:電子商務容量規劃

Dữ kiện:
  - 1M DAU (Daily Active Users)
  - Peak traffic: 3x average
  - Average session: 10 pages, 2 API calls/page
  - Target response time: < 200ms

Tính toán:
  Average QPS = 1M * 20 requests / 86,400s ≈ 230 QPS
  Peak QPS = 230 * 3 = 690 QPS

  Nếu 1 server xử lý 200 QPS:
  Servers cần = 690 / 200 = 3.45 → 4 servers
  + Headroom 30%: 4 * 1.3 = 5.2 → 6 servers

  Tối thiểu: 6 application servers + 1 load balancer

6. 擴充資料庫

6.1 讀取縮放

                    ┌────────────┐
       Writes ────► │   Master   │
                    │  Database  │
                    └──────┬─────┘
                    Replication
               ┌───────────┼───────────┐
          ┌────┴────┐ ┌────┴────┐ ┌────┴────┐
Reads ──► │ Replica │ │ Replica │ │ Replica │
          │   1     │ │   2     │ │   3     │
          └─────────┘ └─────────┘ └─────────┘

6.2 寫入縮放

       ┌──────────────────────────────┐
       │        Shard Router          │
       └──────┬───────┬───────┬───────┘
         ┌────┴──┐ ┌──┴───┐ ┌┴──────┐
         │Shard 1│ │Shard 2│ │Shard 3│
         │ A-H   │ │ I-P   │ │ Q-Z   │
         └───────┘ └───────┘ └───────┘

7. 現實世界的延伸範例

7.1 Netflix

Phase 1 (2007): Monolith + Oracle Database
Phase 2 (2008-2012): Migration to AWS + Microservices
Phase 3 (2012+): 
  - 700+ microservices
  - Horizontal scaling trên AWS
  - Custom load balancing (Zuul)
  - Cache layer (EVCache)
  - 200M+ subscribers globally

7.2 Instagram

2010: 2 servers (1 app + 1 database)
2011: Scale to 14M users
  - 3 Nginx load balancers
  - 25 Django app servers
  - 12 PostgreSQL servers (sharded)
  - 6 Redis servers
  - 4 Memcached servers
2012: Facebook acquisition, 100M+ users
  - Continued horizontal scaling on Facebook infra

8. 總結

概念重點
效能針對 1 個使用者進行了最佳化(程式碼、演算法、快取)
可擴展性處理許多用戶(更多資源)
垂直擴充升級1台機器的配置-簡單但有限
水平縮放增加更多機器 - 複雜但幾乎無限
無國籍水平擴展的先決條件
容量規劃始終在縮放之前進行計算

經驗法則: 從簡單開始(垂直),規劃水平。不要在需要之前進行擴展,而是進行設計,以便您可以在需要時進行擴展。


練習

  1. 容量規劃: 您正在建立一個每日活躍用戶數為 50 萬的送餐應用程式。每位使用者平均每週 5 個訂單,每個訂單產生 10 個 API 呼叫。計算峰值 QPS 和所需伺服器數量(每台伺服器處理 300 QPS)。

  2. 無狀態設計: 目前系統將購物車儲存在伺服器上的會話中。重新設計為無狀態,支援水平擴展。

  3. 擴充決策: 擁有 5 萬用戶的 SaaS 平台,平均回應時間 800 毫秒(目標 < 200 毫秒)。目前伺服器:4 個 vCPU,16GB RAM,CPU 使用率 85%。應該垂直縮放還是水平縮放?解釋。