設計高度可擴展 Web 應用的關鍵考量:從單選題看系統設計核心

深入解析可擴展性設計的正確與錯誤實踐

題目解析

在系統設計面試中,經常會遇到這樣的問題:哪些考慮因素對於設計高度可擴展的 Web 應用程式通常很重要?

讓我們透過分析每個選項,深入理解可擴展性設計的核心原則。

選項分析

讓我們逐一分析每個選項,理解為什麼有些是正確的,有些是錯誤的。

✅ 正確選項

1. Data Partitioning (Sharding) - 資料分片

為什麼正確?

資料分片是處理大規模資料的核心策略。當單一資料庫無法存儲所有資料時,我們需要將資料分散到多個資料庫。

實際應用場景

Instagram 的照片儲存:
- 問題:數十億張照片,單一資料庫放不下
- 解法:按用戶 ID 分片
  - Shard 1: 用戶 1-1000000
  - Shard 2: 用戶 1000001-2000000
  - ...以此類推

分片策略比較

分片策略優點缺點適用場景
範圍分片查詢簡單熱點問題時序資料
雜湊分片分佈均勻範圍查詢困難用戶資料
地理分片低延遲跨區查詢複雜全球服務

3. Asynchronous Processing - 非同步處理

為什麼正確?

非同步處理讓應用能快速回應用戶,同時在背景處理耗時操作。

經典範例

YouTube 影片上傳流程:
1. 用戶上傳影片 → 立即回應「上傳成功」
2. 背景處理:
   - 轉碼成多種格式(480p, 720p, 1080p, 4K)
   - 生成縮圖
   - 內容審核
   - CDN 分發

同步 vs 非同步的差異

同步處理(不可擴展):
  用戶等待時間: 5 分鐘
  伺服器阻塞: 
  用戶體驗: 
  擴展性: 

非同步處理(可擴展):
  用戶等待時間: 5 
  伺服器阻塞: 
  用戶體驗: 
  擴展性: 

5. Eventual Consistency - 最終一致性

為什麼正確?

在分散式系統中,要求即時一致性會嚴重影響效能。最終一致性是一種務實的權衡。

實際案例

Facebook 按讚功能:
- 你按讚 → 立即看到讚數 +1
- 朋友可能 2 秒後才看到更新
- 這種短暫不一致是可接受的

一致性模型比較

模型特點延遲使用場景
強一致性所有節點即時同步銀行轉帳
最終一致性最終會同步社交媒體
弱一致性不保證同步極低快取系統

❌ 錯誤選項

2. Fully Synchronous Write Operations - 完全同步寫入

為什麼錯誤?

完全同步寫入會造成嚴重的效能瓶頸,違背可擴展性原則。

反面教材

錯誤做法:
1. 用戶發文
2. 等待寫入主資料庫 ✓
3. 等待同步到所有備份 ✓  
4. 等待更新所有快取 ✓
5. 等待通知所有粉絲 ✓
→ 用戶等待 30 秒!

正確做法:
1. 用戶發文
2. 寫入訊息佇列
3. 立即回應用戶
→ 背景慢慢處理其他步驟

4. Vertical Scaling on a Single Server - 單一伺服器垂直擴展

為什麼錯誤?

垂直擴展有明顯的上限,無法實現真正的高度可擴展。

垂直擴展的限制

問題一:硬體上限
  CPU: 最多 128 核心
  記憶體: 最多 6TB
  成本: 指數級增長

問題二:單點故障
  伺服器當機 = 服務全掛

問題三:地理限制  
  全球用戶都要連到同一台機器
  延遲問題無法解決

6. Blocking All Read Operations During Writes - 寫入時阻塞讀取

為什麼錯誤?

這種做法會嚴重影響系統可用性和用戶體驗。

為什麼這是災難性的設計

情境:電商網站更新商品價格
錯誤做法:
  - 更新期間所有用戶無法瀏覽商品
  - 每秒損失數萬筆潛在訂單
  
正確做法:
  - 使用 MVCC(多版本併發控制)
  - 讀寫分離
  - 樂觀鎖定

🎯 可擴展性設計的核心原則

1. 無狀態設計(Stateless)

好設計:
- Session 存在 Redis
- 任何伺服器都能處理請求
- 容易水平擴展

壞設計:
- Session 存在伺服器記憶體
- 用戶被綁定到特定伺服器
- 擴展困難

2. 解耦合(Decoupling)

緊耦合系統:
  A服務 → 直接呼叫 → B服務
  問題: B掛了,A也掛

鬆耦合系統:
  A服務 → 訊息佇列 → B服務
  優點: B掛了,訊息會累積,A繼續運作

3. 快取優先(Cache First)

請求路徑:
1. CDN 快取(靜態資源)
2. Redis 快取(熱資料)
3. 應用層快取(計算結果)
4. 資料庫(最後手段)
0%