系統設計權衡取捨
核心觀念
沒有完美的方案,只有適合的方案。
常見權衡
1. 一致性 vs 可用性 (CAP)
| 選擇 |
場景 |
例子 |
| 強一致性 |
金融交易、庫存 |
銀行轉帳 |
| 最終一致性 |
社群動態、搜尋 |
Facebook 按讚 |
2. 延遲 vs 吞吐量
| 選擇 |
場景 |
做法 |
| 低延遲 |
即時遊戲、搜尋 |
快取、CDN |
| 高吞吐量 |
批次處理、分析 |
佇列、批次 |
3. 成本 vs 效能
| 選擇 |
場景 |
做法 |
| 低成本 |
個人專案、原型 |
共用主機、Serverless |
| 高效能 |
大型產品 |
專用機器、快取集群 |
4. 簡單 vs 靈活
| 選擇 |
場景 |
做法 |
| 簡單 |
新創、MVP |
單體架構、單資料庫 |
| 靈活 |
大公司、多團隊 |
微服務、事件驅動 |
5. 即時 vs 非即時
| 選擇 |
場景 |
做法 |
| 即時 |
聊天、通知 |
WebSocket |
| 非即時 |
報表、分析 |
佇列、批次 |
決策框架
遇到權衡時問:
1. 業務需求是什麼?
- 延遲要求?
- 一致性要求?
2. 規模是多少?
- 現在的流量?
- 未來的成長?
3. 成本預算?
- 開發成本?
- 運維成本?
4. 團隊能力?
- 能維護複雜系統嗎?
- 學習成本?
實際案例
案例:電商庫存扣減
問題: 如何確保不會超賣?
| 方案 |
優點 |
缺點 |
| 悲觀鎖 (SELECT FOR UPDATE) |
簡單、可靠 |
效能差 |
| 樂觀鎖 (version check) |
效能好 |
高並發時失敗率高 |
| Redis 原子操作 |
極快 |
需要同步到 DB |
| 預扣庫存 |
效能好 |
流程複雜 |
選擇: 根據流量決定
- 低流量:悲觀鎖簡單可靠
- 高流量:Redis + 異步同步
案例:社群動態
問題: 如何讓用戶看到最新動態?
| 方案 |
優點 |
缺點 |
| Pull (讀時合併) |
寫入簡單 |
讀取慢 |
| Push (寫時擴散) |
讀取快 |
名人問題 |
| 混合方案 |
平衡 |
複雜 |
選擇: 混合方案
- 一般用戶:Push
- 名人:Pull
常見錯誤
❌ 過度設計:簡單問題用複雜方案
❌ 忽視非功能需求:只考慮功能
❌ 沒有 Plan B:單點故障
❌ 過早優化:先讓系統工作,再優化