【系統設計白話文】#02 設計需求與網路基礎 — CAP 定理、延遲與通訊協定

測驗:設計需求與網路基礎 — CAP 定理、延遲與通訊協定

共 5 題,點選答案後會立即顯示結果

1. CAP 定理中的三個字母分別代表什麼?

  • A. Cache、Authentication、Performance
  • B. Concurrency、Availability、Partition Tolerance
  • C. Consistency、Availability、Partition Tolerance
  • D. Consistency、Accessibility、Partition Tolerance

2. DNS 的主要功能是什麼?

  • A. 加密網路傳輸的資料,保護隱私
  • B. 將人看得懂的網域名稱翻譯成電腦看得懂的 IP 位址
  • C. 管理伺服器之間的資料同步
  • D. 監控伺服器的延遲和吞吐量

3. 在高速公路的比喻中,「車道數」對應到系統設計中的哪個指標?

  • A. 延遲(Latency)
  • B. P99 回應時間
  • C. SLA 百分比
  • D. 吞吐量(Throughput)

4. 為什麼串流影片通常使用 UDP 而不是 TCP?

  • A. 因為 UDP 可以加密資料,TCP 不行
  • B. 因為 UDP 保證資料按順序到達,觀看體驗更好
  • C. 因為 UDP 速度快,掉幾個畫面使用者感覺不到,但用 TCP 重傳掉落封包會造成卡頓
  • D. 因為 UDP 有三次握手機制,連線更穩定

5. 一個銀行交易系統在網路分區發生時,選擇拒絕服務也不允許資料不一致。這個系統屬於 CAP 中的哪種類型?為什麼?

  • A. AP 系統 — 因為它優先保證可用性,讓使用者隨時能操作
  • B. CP 系統 — 因為它寧可暫時不能用,也要確保資料一致性
  • C. CA 系統 — 因為銀行不允許網路分區發生
  • D. CP 系統 — 因為它優先保證傳輸速度,使用 UDP 協定

**系列**:系統設計白話文(第 2 篇,共 5 篇)
**難度**:L2-進階
**前置知識**:【系統設計白話文】#01 電腦架構全景圖
**影片來源**:freeCodeCamp — *System Design Concepts Course and Interview Prep* by Hayk Simonyan


這篇在講什麼?

上一篇我們看了單台電腦的架構。但真實世界的系統不會只有一台機器 — 它們是分散在多台伺服器上、透過網路互相溝通的。

這篇要回答一個核心問題:當系統分散到多台機器上,會遇到什麼新問題?

讀完後你會看懂:

  • 為什麼分散式系統「不可能同時要快、要穩、又要一致」(CAP 定理)
  • 「延遲」和「吞吐量」到底在量什麼
  • TCP 和 UDP 這兩個你一定聽過的協定差在哪
  • 你在瀏覽器輸入網址後,DNS 怎麼幫你找到伺服器

一、CAP 定理:三選二的殘酷現實

一句話說明

分散式系統在「一致性、可用性、分區容錯」三個好處裡,最多只能同時保證兩個

三個名詞翻譯

英文 中文 白話意思
Consistency 一致性 不管問哪台伺服器,拿到的資料都一樣
Availability 可用性 不管什麼時候發請求,系統都會回應
Partition Tolerance 分區容錯性 就算伺服器之間斷線了,系統還是能運作

用銀行 ATM 的例子秒懂

想像你有一個銀行帳戶,存了 10,000 元。這個銀行在台北和高雄各有一台 ATM,兩台的資料要保持同步。

正常情況:你在台北 ATM 領了 3,000 元,兩台 ATM 馬上同步,餘額都顯示 7,000 元。三個好處全都有。

但如果台北和高雄的網路斷了呢?(這就是「分區」發生了)

這時銀行只有兩個選擇:

選項 A:選一致性(CP)
─────────────────────
台北 ATM:「網路斷了,我無法確認資料是否最新,
          所以我拒絕讓你領錢。」
結果:資料一定正確,但你用不了 → 犧牲可用性

選項 B:選可用性(AP)
─────────────────────
台北 ATM:「網路斷了,但我還是讓你領錢。
          等網路恢復再同步。」
結果:你隨時可以用,但可能兩台餘額暫時不一樣 → 犧牲一致性

為什麼不能三個都要?

因為分區(P)在真實網路中一定會發生 — 網路線會斷、路由器會掛。所以 P 幾乎是必選的,你真正在選的是 C 或 A。

真實世界的選擇:

CP 系統(一致性 + 分區容錯)
├── 銀行交易系統 → 寧可暫時不能用,也不能算錯帳
├── 分散式鎖 → 要確保同時只有一個人拿到鎖
└── 例子:MongoDB(預設)、HBase

AP 系統(可用性 + 分區容錯)
├── 社群媒體的按讚數 → 暫時少顯示幾個讚沒關係
├── DNS 系統 → 寧可回傳舊資料也不要沒回應
└── 例子:Cassandra、DynamoDB

Vibe Coder 檢查點

當你看到架構文件提到 CAP 時:

  • [ ] 這個系統選的是 CP 還是 AP?
  • [ ] 資料「暫時不一致」對使用者的影響大嗎?(金錢交易 vs 按讚數)
  • [ ] 系統用了什麼機制來處理網路分區後的資料同步?

二、吞吐量與延遲:兩個常被搞混的指標

一句話說明

延遲是「一件事要多久才完成」,吞吐量是「同一時間能處理多少件事」。

高速公路比喻

延遲(Latency)= 開車從 A 到 B 要多久
                  例:台北到台中 2 小時

吞吐量(Throughput)= 高速公路同時能跑幾台車
                      例:四線道 = 每小時通過 4,000 台車

關鍵觀念:加寬車道(提高吞吐量)不會讓每台車開更快(降低延遲)。這是兩個獨立的維度。

對應到系統設計

指標 衡量什麼 單位 比喻
Latency(延遲) 一個請求從發出到收到回應的時間 毫秒(ms) 車程時間
Throughput(吞吐量) 系統每秒能處理多少請求 RPS(requests/sec) 車道數

你會在文件裡看到的寫法

# 效能報告常見格式

延遲指標:
  P50 = 120ms     ← 50% 的請求在 120ms 內完成(中位數)
  P95 = 350ms     ← 95% 的請求在 350ms 內完成
  P99 = 800ms     ← 99% 的請求在 800ms 內完成

吞吐量指標:
  平均 RPS = 15,000    ← 每秒處理 15,000 個請求
  峰值 RPS = 42,000    ← 高峰時每秒 42,000Code language: PHP (php)

為什麼要看 P95、P99? 因為平均值會騙人。如果 99% 的使用者等 100ms,但 1% 的使用者等 10 秒,平均值看起來「只有 200ms」,但那 1% 的人體驗很差。


三、SLO 與 SLA:對使用者的承諾

一句話說明

SLO 是「我們系統要達到的效能目標」,SLA 是「我們對客戶承諾的效能,做不到就賠錢」。

名詞翻譯

縮寫 全名 白話意思
SLI Service Level Indicator 實際量到的數字(例:今天 uptime 是 99.95%)
SLO Service Level Objective 團隊內部設的目標(例:我們的目標是 99.9% uptime)
SLA Service Level Agreement 寫在合約裡的承諾(例:低於 99.9% 就退費)

99.9% Uptime 到底是多少停機時間?

99%    的 uptime = 每年可停機 3.65 天     ← 相當寬鬆
99.9%  的 uptime = 每年可停機 8.76 小時   ← 大部分雲端服務的標準
99.99% 的 uptime = 每年可停機 52.6 分鐘   ← 很嚴格
99.999%的 uptime = 每年可停機 5.26 分鐘   ← 電信等級,極少系統能做到

白話翻譯:每多一個 9,難度就高一個量級,成本也是。

Vibe Coder 檢查點

當你在選雲端服務或讀架構文件時:

  • [ ] 這個服務的 SLA 是幾個 9?
  • [ ] SLA 裡的「可用性」是怎麼定義的?(有些服務算的是月平均,不是每分鐘)
  • [ ] 違反 SLA 的補償是什麼?(通常是服務額度,不是現金)

四、IP 位址:網路世界的門牌號碼

一句話說明

IP 位址是每台連上網路的裝置的唯一識別碼,就像門牌號碼讓郵差知道信要送去哪。

兩種格式

IPv4:203.0.113.42
      ↑ 四組數字,每組 0-255,用點分隔
      ↑ 總共約 43 億個地址(已經不夠用了)

IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334
      ↑ 八組十六進位數字,用冒號分隔
      ↑ 地址數量多到可以給地球每粒沙子分一個
Code language: CSS (css)

IP 封包的結構(知道就好)

每次你的電腦發送資料時,資料前面會加上一個「信封」(IP 標頭):

┌─────────────────────────────────┐
│           IP 標頭               │
│  ┌───────────┬───────────────┐  │
│  │ 來源 IP    │ 203.0.113.42  │  │ ← 寄件人地址
│  │ 目的 IP    │ 198.51.100.1  │  │ ← 收件人地址
│  │ TTL       │ 64            │  │ ← 最多經過 64 個路由器就丟棄
│  │ 協定      │ TCPUDP    │  │ ← 用哪種方式傳送
│  └───────────┴───────────────┘  │
├─────────────────────────────────┤
│           資料內容               │
│  (你真正要傳的東西)              │
└─────────────────────────────────┘
Code language: CSS (css)

白話翻譯:IP 標頭就是信封上的寄件/收件地址,讓網路知道這包資料從哪來、要去哪。


五、TCP vs UDP:兩種資料傳輸方式

一句話說明

TCP 是掛號信(慢但保證送到),UDP 是傳單(快但可能掉)。

對照比較

特性 TCP UDP
全名 Transmission Control Protocol User Datagram Protocol
比喻 掛號信 傳單
保證送達? 是,沒收到會重傳 不保證
資料順序? 保證按順序到達 不保證順序
速度 較慢(有額外確認步驟) 較快(發了就走)
適合場景 網頁、檔案下載、Email 串流影片、遊戲、視訊通話

TCP 的三次握手(最小範例)

TCP 在傳資料之前,雙方要先「握手」確認彼此都在:

你的電腦                        伺服器
    │                             │
    │── 1. SYN:「嘿,在嗎?」──→ │
    │                             │
    │←─ 2. SYN-ACK:「在,你呢?」│
    │                             │
    │── 3. ACK:「我也在,開始吧」→│
    │                             │
    │←──── 正式開始傳資料 ────→   │

白話翻譯:就像打電話 — 你先說「喂」,對方回「喂,聽到了」,你再說「好,我要開始講了」。確認雙方都準備好了才開始講正事。

UDP:發了就走

你的電腦                        伺服器
    │                             │
    │── 資料 1 ──────────────→    │  ✓ 收到
    │── 資料 2 ──────────────→    │  ✗ 掉了(沒人知道)
    │── 資料 3 ──────────────→    │  ✓ 收到
    │── 資料 4 ──────────────→    │  ✓ 收到

為什麼串流影片用 UDP? 因為看影片時,掉一兩個畫面你根本感覺不到,但如果用 TCP 一直重傳掉落的封包,影片就會卡頓。快比完整更重要

你會在程式碼裡看到的樣子

當 AI 幫你寫網路程式時,你可能會看到這些:

import socket

# TCP 連線 — 看到 SOCK_STREAM 就是 TCP
tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#                                          ↑ STREAM = 串流 = TCP

# UDP 連線 — 看到 SOCK_DGRAM 就是 UDP
udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#                                          ↑ DGRAM = Datagram = UDP
Code language: PHP (php)

必看懂SOCK_STREAM = TCP,SOCK_DGRAM = UDP。名字不直覺,但出現頻率很高。

Vibe Coder 檢查點

當你看到網路相關的程式碼或架構時:

  • [ ] 用的是 TCP 還是 UDP?(看 STREAM 或 DGRAM)
  • [ ] 如果是即時應用(遊戲、視訊),用 UDP 是合理的
  • [ ] 如果是要保證資料完整(API 呼叫、檔案傳輸),應該用 TCP

六、DNS:網路世界的電話簿

一句話說明

DNS 把人看得懂的網址(google.com)翻譯成電腦看得懂的 IP 位址(142.250.185.14)。

為什麼需要 DNS?

你記得住:google.com
你記不住:142.250.185.14

DNS 的工作:幫你把 google.com 翻譯成 142.250.185.14
Code language: CSS (css)

DNS 解析流程(完整版)

當你在瀏覽器輸入 www.example.com 後,背後發生了這些事:

步驟 1:先查本機快取
你的電腦:「我之前查過 www.example.com 嗎?」
  → 有快取 → 直接用,結束
  → 沒快取 → 繼續往下問

步驟 2:問 DNS 遞迴解析器(通常是你的 ISP 或 8.8.8.8)
解析器:「我知道 www.example.comIP 嗎?」
  → 有快取 → 直接回覆
  → 沒快取 → 幫你去問

步驟 3:問根域名伺服器(Root Server)
解析器:「.com 的管理者是誰?」
根伺服器:「去問 .com 頂級域名伺服器,地址是 xxx」

步驟 4:問 .com 頂級域名伺服器(TLD Server)
解析器:「example.com 的管理者是誰?」
TLD 伺服器:「去問 example.com 的權威域名伺服器,地址是 yyy」

步驟 5:問權威域名伺服器(Authoritative Server)
解析器:「www.example.comIP 是什麼?」
權威伺服器:「是 93.184.216.34」

步驟 6:回傳結果
解析器把 93.184.216.34 回傳給你的電腦,
你的電腦把結果存進快取,下次就不用再問了。
Code language: CSS (css)

簡化版一張圖

你的瀏覽器
    │
    │ www.example.comIP 是?
    ▼
DNS 遞迴解析器(中間人)
    │
    ├──→ 根伺服器:「.com 去找 TLD 伺服器」
    ├──→ TLD 伺服器:「example.com 去找權威伺服器」
    └──→ 權威伺服器:「IP 是 93.184.216.34」
    │
    │ 93.184.216.34
    ▼
你的瀏覽器 → 連線到 93.184.216.34
Code language: CSS (css)

你可以在終端機試試看

# 查詢一個網域的 IP(你可以直接在終端機跑)
nslookup google.com

# 更詳細的查詢(會顯示整個 DNS 查詢路徑)
dig google.com
Code language: CSS (css)
# nslookup 的輸出大概長這樣:
Server:    8.8.8.8          ← 你用的 DNS 伺服器
Address:   8.8.8.8#53DNS 固定用 port 53

Name:      google.com       ← 你查的網域
Address:   142.250.185.14   ← 對應的 IP 位址
Code language: CSS (css)

有趣的事實

DNS 查詢用的是 UDP(不是 TCP),因為查詢內容很小,速度比可靠性重要。如果 UDP 封包掉了,瀏覽器就再發一次查詢就好。

Vibe Coder 檢查點

當你部署應用或設定網域時:

  • [ ] DNS 設定有沒有正確指向你的伺服器 IP?
  • [ ] DNS 快取的 TTL(Time To Live)是多少?改了 DNS 記錄後可能要等快取過期才生效
  • [ ] 用 nslookupdig 驗證 DNS 是否解析正確

整篇重點回顧

必看懂(核心概念):

CAP 定理    → 分散式系統只能三選二,真實世界通常是 CP 或 AP
延遲        → 一個請求多久完成(看 P95、P99)
吞吐量      → 每秒能處理多少請求(看 RPS)
TCP         → 可靠但慢,用於網頁和 API(看到 SOCK_STREAM)
UDP         → 快但不保證,用於串流和遊戲(看到 SOCK_DGRAM)
DNS         → 把網址翻譯成 IP 位址

知道就好(遇到再查):

SLI/SLO/SLA → 效能承諾的三個層級
IPv4 vs IPv6 → 舊版地址快用完,新版很長但數量幾乎無限
IP 標頭      → 每個網路封包前面的「信封」資訊
DNS 記錄類型  → A、AAAA、CNAME、MX 等不同用途的記錄

下一篇預告

下一篇我們會進入應用層協定 — HTTP、REST API、WebSocket,這些是你每天都在用(但不一定理解)的東西。當你用 AI 寫一個 API,它回傳的 200、404、500 到底是什麼意思?我們下篇見。

進階測驗:設計需求與網路基礎 — CAP 定理、延遲與通訊協定

測驗目標:驗證你是否能在實際情境中應用所學。
共 5 題,包含情境題與錯誤診斷題。

1. 你正在設計一個社群媒體的「按讚數」功能。這個系統分散在全球多個資料中心。產品經理要求:使用者按讚後,即使資料中心之間暫時斷線,頁面也絕對不能顯示錯誤。你會選擇哪種 CAP 策略? 情境題

  • A. CP 系統 — 確保所有資料中心的按讚數完全一致,斷線時拒絕顯示
  • B. AP 系統 — 優先保證頁面可用,允許不同資料中心暫時顯示不同的按讚數
  • C. CA 系統 — 同時保證一致性和可用性,避免網路分區發生
  • D. CP 系統 — 用 TCP 三次握手確保資料中心之間不會斷線

2. 你的 API 效能報告顯示以下數據。PM 說有使用者反映「偶爾很慢」,但平均回應時間看起來不錯。你應該重點關注哪個指標來找出問題? 情境題

延遲指標: P50 = 85ms P95 = 220ms P99 = 4,200ms 吞吐量指標: 平均 RPS = 12,000
  • A. P50(85ms)— 中位數回應時間代表大部分使用者的體驗
  • B. 平均 RPS(12,000)— 吞吐量不足可能導致部分使用者變慢
  • C. P99(4,200ms)— 有 1% 的請求等了超過 4 秒,這就是「偶爾很慢」的來源
  • D. P95(220ms)— 5% 的使用者等超過 200ms,這已經算慢了

3. 你正在開發一款多人即時對戰遊戲。玩家的位置資訊需要每秒更新數十次。如果偶爾掉一兩個位置更新,玩家幾乎不會察覺,但如果有明顯的延遲則會嚴重影響遊戲體驗。你應該使用哪種傳輸協定? 情境題

  • A. TCP — 因為保證資料按順序到達,玩家動作不會亂跳
  • B. TCP — 因為三次握手可以確保連線品質
  • C. UDP — 因為 UDP 可以加密傳輸,適合遊戲的安全性需求
  • D. UDP — 因為速度比完整性重要,掉一兩個封包不影響體驗,但 TCP 的重傳機制會造成延遲

4. 同事更新了網站的 DNS 記錄,將網域指向新的伺服器 IP。但更新後他發現瀏覽器仍然連到舊伺服器。他嘗試了重新整理頁面、清除瀏覽器快取,但都沒用。最可能的原因是什麼? 錯誤診斷

$ nslookup mysite.com Server: 8.8.8.8 Address: 8.8.8.8#53 Name: mysite.com Address: 10.0.0.1 ← 這是舊的 IP(新的應該是 10.0.0.2)
  • A. DNS 伺服器掛了,無法處理新的記錄更新
  • B. DNS 遞迴解析器(8.8.8.8)的快取尚未過期,仍回傳舊的 IP,需要等 TTL 到期才會更新
  • C. 因為 DNS 用 UDP 傳輸,更新封包在傳送途中掉了,需要改用 TCP
  • D. 網域的權威伺服器拒絕了更新請求,需要重新提交

5. 你在看一段 AI 生成的 Python 程式碼,這段程式要建立一個即時影音串流的連線。你覺得這段程式碼有什麼問題? 錯誤診斷

import socket # 建立即時影音串流的連線 stream_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) stream_socket.connect((“streaming.example.com”, 8080)) # 開始傳送影音資料… stream_socket.sendall(video_data)
  • A. 應該使用 socket.AF_INET6 而不是 socket.AF_INET,因為 IPv4 地址不夠用
  • B. port 8080 不適合串流,應該改用標準的 port 443
  • C. 影音串流應該使用 SOCK_DGRAM(UDP)而不是 SOCK_STREAM(TCP),因為串流需要速度而非完整性
  • D. sendall() 方法不適合大量資料傳輸,應該改用 send()

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *