系統設計方法論與容量估算#
面對一道開放式系統設計題,最容易犯的錯誤是「還沒釐清需求就開始畫架構」。本節整理一套可重複套用的四步驟框架,搭配「信封背面估算 (Back-of-the-envelope Estimation)」常用的記憶表,讓你在白板前能快速把規模、延遲、可用率換算成具體的設計取捨。
本節是後續案例(限流器、一致性雜湊、發號器、鍵值儲存)共用的「前置動作」。
四步驟框架#
flowchart LR
S1["1. 釐清需求<br/>Understand &<br/>Scope (3-10 min)"]
S2["2. 高階設計<br/>High-level Design<br/>(10-15 min)"]
S3["3. 深入細節<br/>Design Deep Dive<br/>(10-25 min)"]
S4["4. 收尾<br/>Wrap Up<br/>(3-5 min)"]
S1 --> S2 --> S3 --> S4
S3 -.重新釐清.-> S1| 步驟 | 目標 | 重點動作 |
|---|---|---|
| 1 釐清需求 | 確立功能與非功能需求、邊界 | 問問題、列出功能/非功能需求、確認規模,不要急著給方案 |
| 2 高階設計 | 畫出整體藍圖並取得共識 | Client/API/服務/儲存/快取/CDN/佇列 方塊圖、信封背面估算 |
| 3 深入細節 | 挑選關鍵元件深挖 | 雜湊函式、降低延遲、狀態管理;展現取捨能力,勿迷失細節 |
| 4 收尾 | 找瓶頸、談演進 | 瓶頸與改進、故障情境與復原、監控/部署/再擴展 |
深入細節時若發現需求不清,要回到步驟 1。 系統設計不是線性流程;在步驟 3 暴露的歧義(例如「排序規則」「媒體型別」)往往會推翻步驟 2 的藍圖。
釐清需求問題清單#
在動筆前,至少要問清楚這幾類問題:
- 我們要做哪些具體功能?哪些是最重要的核心功能?
- 目前有多少使用者?預期 3 個月 / 6 個月 / 1 年的成長到多大規模?
- 流量規模(DAU、QPS)大概多少?讀寫比例如何?
- 支援哪些媒體型別(純文字、圖片、影片)?
- 結果如何排序 / 排名?
- 是行動 App、Web,還是兩者都要?
- 公司現有技術棧是什麼?有哪些既有服務可以直接複用?
信封背面估算#
2 的次方記憶表#
資料量單位本質是 2 的次方,但估算時常以 10 進位近似:
| 次方 | 近似值 (10 進位) | 單位 | 簡稱 |
|---|---|---|---|
| 2^10 | 1,000 | Kilobyte | KB |
| 2^20 | 1,000,000 | Megabyte | MB |
| 2^30 | 1,000,000,000 | Gigabyte | GB |
| 2^40 | 1,000,000,000,000 | Terabyte | TB |
| 2^50 | ~10^15 | Petabyte | PB |
常見延遲數字#
「每位工程師都該知道的延遲數字」——記住數量級就能判斷瓶頸在哪:
| 操作 | 延遲 | 換算 |
|---|---|---|
| L1 cache 參照 | 0.5 ns | |
| 分支預測失敗 (branch mispredict) | 5 ns | |
| L2 cache 參照 | 7 ns | |
| Mutex 上鎖/解鎖 | 100 ns | |
| 主記憶體參照 | 100 ns | |
| 用 Zippy 壓縮 1 KB | 10 µs | 10,000 ns |
| 透過 1 Gbps 網路傳 2 KB | 20 µs | 20,000 ns |
| 從記憶體循序讀 1 MB | 250 µs | 250,000 ns |
| 同一資料中心往返 (RTT) | 500 µs | 0.5 ms |
| 磁碟尋道 (disk seek) | 10 ms | 10,000,000 ns |
| 從磁碟循序讀 1 MB | 30 ms | |
| 跨洲往返 (加州 ↔️ 荷蘭) | 150 ms |
三條啟示:記憶體快、磁碟慢(避免 disk seek);傳輸前先壓縮;跨資料中心 / 跨洲的 RTT 是設計多區域系統的硬性下限。SSD 隨機讀約 150 µs,介於記憶體與磁碟之間,這也是 鍵值儲存 用 SSTable + Bloom filter 的前提。
可用率 ↔️ 停機時間#
非功能需求中最常被量化的是可用率 (Availability),習慣以「幾個 9」表示:
| 可用率 | 每日停機 | 每年停機 |
|---|---|---|
| 99% | 14.40 分鐘 | 3.65 天 |
| 99.9% | 86.40 秒 | 8.76 小時 |
| 99.99% | 8.64 秒 | 52.6 分鐘 |
| 99.999% | 864 毫秒 | 5.26 分鐘 |
| 99.9999% | 86.4 毫秒 | 31.56 秒 |
每多一個 9,成本與架構複雜度往往呈非線性上升(冗餘、故障切換、跨區複製)。可用率與一致性的取捨屬 CAP 範疇,理論細節見 分散式系統基礎 — CAP 定理。
QPS、尖峰與儲存估算#
估算的核心是把「使用者行為」逐步換算成「每秒請求數」與「總容量」:
$$ \text{DAU} = \text{MAU} \times \text{每日活躍比例} $$
$$ \text{平均 QPS} = \frac{\text{DAU} \times \text{每人每日操作數}}{86400} $$
$$ \text{尖峰 QPS} \approx 2 \times \text{平均 QPS} $$
$$ \text{儲存量} = \text{DAU} \times \text{每日操作數} \times \text{單筆大小} \times \text{保留天數} $$
工作範例:Twitter 類服務
假設:
- 月活躍使用者 (MAU) 3 億,日活躍比例 50% ➡️ DAU = 1.5 億
- 每人每天發 2 則貼文,其中 10% 含媒體(每則媒體約 1 MB)
- 資料保留 5 年
計算:
- 平均寫入 QPS:$\dfrac{1.5 \times 10^8 \times 2}{86400} \approx 3{,}500$ QPS
- 尖峰 QPS:$2 \times 3{,}500 \approx 7{,}000$ QPS
- 每日媒體量:$1.5 \times 10^8 \times 2 \times 10% \times 1,\text{MB} = 30$ TB/天
- 5 年媒體量:$30,\text{TB} \times 365 \times 5 \approx 55$ PB
得到 30 TB/天的寫入量後,馬上就能推導出「單機放不下,必須分片 + 複製」的結論——這正是進入 一致性雜湊 與 鍵值儲存 的觸發點。
小結#
| 階段 | 你該交付什麼 |
|---|---|
| 釐清需求 | 一份功能/非功能需求清單與規模假設 |
| 估算 | QPS、尖峰 QPS、儲存量的數量級 |
| 高階設計 | 含主要元件與資料流的方塊圖 |
| 深入細節 | 1~2 個關鍵元件的取捨論證 |
| 收尾 | 瓶頸、故障情境、未來再擴展方向 |
估算的目的不是算到小數點正確,而是得到正確的數量級,好讓你判斷「要不要快取、要不要分片、要不要多區域」。數字本身會引導出架構。