EP.01系統設計

系統設計思維:
從需求分解到架構決策

面試官問「設計一個 Instagram」,你該從哪裡開始? 這篇建立系統設計的思考框架:如何拆解需求、估算容量、 一步步做出有依據的架構決策。

Joseph Chen 2026 15 min read System Design · Scalability · Architecture · Interview

「系統設計沒有唯一正確答案,只有在特定約束條件下更好或更差的取捨。 一個能說清楚『我選這個方案是因為 X,代價是 Y,但在這個規模下可以接受』的工程師, 比背答案的人值錢十倍。」

— 大型系統設計面試核心原則

為什麼系統設計「感覺很難」?

系統設計難不在於技術本身,而在於它沒有固定答案。 演算法題有正確解,系統設計題是在模糊需求下做取捨。 初學者最常犯的錯誤有三個:

01

直接跳進實作細節

「我會用 Redis 做快取,然後加一個 message queue,然後...」——等等,我們連用戶量是多少都不知道,為什麼先設計快取?

02

把系統設計當技術名詞清單

把所有聽過的技術全丟進去:Kafka、Redis、ElasticSearch、CDN...但說不清楚為什麼用這個,而不是更簡單的方案。

03

忽略約束條件(Constraints)

每個系統都有它的脈絡:預算、團隊規模、維護成本、延遲要求。「最好的架構」是在這些約束下最合適的,不是技術上最酷的。

正確的思考順序

釐清需求估算規模確認約束設計高層架構深入關鍵模組識別瓶頸提出優化方案

Step 1:需求釐清(Requirements Clarification)

永遠是第一步,花 5 分鐘在這裡,能省 30 分鐘的冤枉路

面試官說「設計 URL Shortener」,這個描述至少有十種不同的系統。 在設計之前,你需要問到兩類需求:

功能性需求(Functional)

系統「要做什麼」

用戶能縮短 URL?

能自訂短網址後綴?

短網址有過期時間嗎?

需要點擊次數統計嗎?

需要使用者帳號系統嗎?

非功能性需求(Non-Functional)

系統「要多好」

讀寫比例是多少?(read-heavy?)

延遲要求?(p99 < 100ms?)

可用性要求?(99.9%? 99.99%?)

一致性 vs 可用性如何取捨?

資料需要持久化多久?

📝 範例:URL Shortener 的需求確認結果

功能: 縮短 URL、redirect、點擊統計
規模: 100M DAU,讀寫比 = 100:1(讀多寫少)
延遲: redirect p99 < 50ms
可用性: 99.9%(允許每年約 8 小時 downtime)
一致性: 最終一致性可接受(統計資料)
保存期限: 預設 5 年,可自訂

Step 2:容量估算(Capacity Estimation)

「大概」的數字比沒有數字好,數量級對了就夠了

估算的目的不是精確,而是判斷架構規模: 一台機器夠不夠?需不需要分片?需不需要快取? 先記住幾個常用數字:

86K
次/天
1 req/秒的日請求量(86400s)
2.5M
次/月
1 req/秒的月請求量(86400 × 30)
1KB
/條
一條一般文字記錄
1MB
= 10⁶ B
百萬位元組
1GB
= 10⁹ B
十億位元組
1TB
= 10¹² B
一兆位元組
300ms
RTT
US → Asia 往返延遲
100ms
上限
用戶感知到的「慢」

實戰估算:URL Shortener(100M DAU)

📊 QPS(每秒請求數)

寫入(縮短 URL):100M DAU × 0.1 次 / 86400s ≈ 115 寫入/s
讀取(redirect):100:1 讀寫比 → 11,500 讀取/s ≈ 12K QPS
峰值:平均的 2x → 24K QPS(讀取)

💾 儲存空間

每條記錄:原始 URL(2KB) + 短碼(7B) + 時間戳(8B) ≈ 2.1KB
每天新增:115 寫入/s × 86400s × 2.1KB ≈ 20GB/天
5 年總量:20GB × 365 × 5 ≈ 36TB

🔑 短碼需求

5 年總 URL 數:115/s × 86400 × 365 × 5 ≈ 18 億條
7 位 Base62(a-z,A-Z,0-9):62⁷ ≈ 3.5 兆,足夠
結論:7 位短碼即可覆蓋 5 年需求
估算結論:12K QPS 的讀取量已超過單台 DB 能扛的上限(約 1K~5K QPS), 必須引入快取(Redis)。36TB 的資料量需要考慮資料庫分片(Sharding)策略。 這兩個數字直接影響後續的架構決策。

Step 3:高層架構設計(High-Level Design)

先畫方塊圖,再說每個方塊的職責

估算結果是架構的「輸入」,不是終點。 12K QPS 告訴你需要快取;36TB 告訴你需要分片——這些數字現在要轉換成具體的元件與資料流。 高層架構設計的原則是:先確認誰負責什麼,再討論怎麼做

URL Shortener 高層架構

Client(Browser / App)
↓ HTTPS Request
Load Balancer

distribute traffic

↓ route to service
Write Service

縮短 URL

Read Service

redirect

Analytics Service

點擊統計

↓ write↓ read (Cache first)↓ async
Redis Cache

hot URLs, TTL

Primary DB

URL 對照表

Analytics DB

ClickHouse / BigQuery

注意這個架構把讀寫分離成兩個服務(Write Service / Read Service)。 這是因為我們算出讀取是 12K QPS,但寫入只有 115 QPS——兩者規模差一百倍, 分開設計讓各自可以獨立擴縮(Scale Out)。

Step 4:深入關鍵模組

面試官通常會指定一個模組讓你深入

以 URL Shortener 為例,最值得深入的是「短碼生成策略」。 這看起來簡單,但真正做到不重複、高可用,有幾種思路:

方案 A:雜湊截斷(MD5 / SHA-256)

✅ 優點

實作簡單

相同 URL 產生相同短碼(去重)

❌ 缺點

Hash 碰撞需處理

難以支援自訂後綴

// MD5 前 7 碼
const shortCode = md5(originalUrl).slice(0, 7);
// 問題:碰撞時如何處理?遞增後綴直到不衝突

方案 B:全局自增 ID(Auto-increment)

✅ 優點

唯一性保證

可 Base62 encode 成短碼

❌ 缺點

單點瓶頸(DB 序列)

可預測的 ID(安全疑慮)

// DB 自增 ID → Base62
function toBase62(id: number): string {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
  let result = '';
  while (id > 0) {
    result = chars[id % 62] + result;
    id = Math.floor(id / 62);
  }
  return result;
}

方案 C:分散式 ID(Snowflake / UUID)

✅ 優點

無單點瓶頸

分散式環境安全產生

❌ 缺點

UUID 太長(需截斷)

Snowflake 需時鐘同步

// Snowflake ID: 64 bits
// [1 bit 符號][41 bit 時間戳][10 bit 機器 ID][12 bit 序列號]
// 可每毫秒產生 4096 個不重複 ID,不需中央協調

📌 Ticket Server 是什麼?

Ticket Server 是解決「分散式環境下全局唯一自增 ID」的輕量方案。 做法是:有一台專用的 DB,只做一件事——維護一個 counter 並批量發放 ID 段。 每個服務啟動時或用完本地 ID 池後,向 Ticket Server 請求一批 ID(例如 1000 個), 之後在本地順序使用,不需要每次生成 ID 都打 DB。 這樣 Ticket Server 的 QPS 壓力降為實際生成 QPS / 批次大小(1000),同時 ID 保持有序(對 B-Tree 索引友好)。

🎯 面試建議答法

「我選方案 B(自增 ID + Base62)搭配 Ticket Server 解決單點問題: 用一台專用的 Ticket DB 批量發放 ID 段(例如每次領取 1000 個), 服務在本地消化這 1000 個 ID 再去領下一批。 這樣 Ticket Server 的壓力降為 QPS / 1000,且服務有本地 ID 池不依賴 DB 每次請求。」

通用系統設計框架(可套用任何題目)

1

釐清需求

5 min

功能性需求(做什麼)+非功能性需求(多快、多穩、多大)

2

容量估算

5 min

估算 QPS、儲存量、頻寬。數量級對了就夠,不要糾結精確數字

3

高層架構

10 min

畫方塊圖,確認主要元件、資料流、讀寫路徑

4

深入關鍵模組

15 min

根據面試官指引,深入一個或兩個最複雜的子問題

5

識別瓶頸與優化

5 min

SPOF(單點故障)、熱點(hot key)、跨區延遲、一致性問題

必知的系統設計取捨

取捨維度選 A選 B何時選 A?
一致性 vs 可用性強一致(CP)最終一致(AP)金融交易、庫存扣減
讀延遲 vs 寫延遲Read-through CacheWrite-through Cache讀多寫少(>10:1)
SQL vs NoSQLSQL(關聯式)NoSQL(文件/KV)結構化、需要 JOIN、ACID
垂直擴展 vs 水平擴展Scale Up(更大機器)Scale Out(更多機器)初期簡單,有上限
同步 vs 非同步同步處理非同步 Queue非核心路徑、可延遲處理

重點整理

先問需求再動手

功能性 + 非功能性需求確認清楚,才能判斷架構方向。跳過這步是最常見的失誤。

估算決定架構

12K QPS → 需要快取;36TB → 需要分片。數字是架構決策的依據,不是裝飾。

先廣後深

先畫方塊圖(30 分鐘內),再由面試官指引深入特定模組。別一開始就死在細節裡。

說清楚取捨

每個決策都要說「我選 X 而不是 Y,是因為在我們的場景下 Z 更重要」。沒有取捨的設計是沒想清楚的設計。

System Design
Architecture

下一篇

EP.02 負載均衡