iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
Software Development

30 天從 Full-Stack Engineer 進化到 System Design:從 0 設計可支撐百萬使用者的系統系列 第 14 篇

# Day 14|CAP Theorem:Consistency、Availability、Partition 到底為什麼不能全部都要?

  • 分享至 

  • xImage
  •  

Day 13 最後我們看到:

Server A ✅
Network ❌
Server B ✅

兩台 Server 都活著,卻無法互相溝通。這叫 Network Partition。

假設 A 收到 Write:

balance: $1,000 → $500

但 Update 無法傳給 B,因此:

A = $500
B = $1,000

此時 User 對 B Read,B 到底應該繼續回 $1,000,還是拒絕 Request?

這就是今天 CAP Theorem 要幫我們理解的問題。


Theorem 是什麼?

Theorem 中文通常翻成「定理」。

可以先理解成:

經過數學或邏輯方式證明成立的一個結論。

CAP Theorem 不是 Database Product,也不是 Design Pattern,而是在描述
Distributed System 在特定情況下受到的限制。


CAP 是哪三個字?

C = Consistency
A = Availability
P = Partition Tolerance

重點不是背縮寫,而是理解每個字真正代表什麼。


C:Consistency

Day 13 已經學過 Consistency。

在 CAP 的情境,可以先理解成:

每次成功的 Read,都像是在讀同一份最新資料。

例如:

Initial:
A = $1,000
B = $1,000

Write to A:
A = $500

如果要維持這種 Consistency,B 就不能再成功把舊的 $1,000 當成最新 State
回傳。


View 是什麼?

這裡的 View 不是 Frontend UI。

它代表:

某個 Node 目前看到 / 知道的資料狀態。

例如:

A's View → $500
B's View → $1,000

代表兩邊對同一份 Data 的 View 不一樣。


Node 是什麼?

Node:

Distributed System 中參與工作的其中一台 Machine、Server 或
Instance。

例如:

Database Node A
Database Node B
Database Node C

CAP 討論的就是多個 Node 透過 Network Communication 工作時的問題。


A:Availability

一般來說,Availability 可以理解成:

System 在 User 需要時能不能正常提供 Service。

在 CAP 的情境,要再精確一點:

一個仍能正常工作的 Node 收到 Request 後,要能在有限時間內給出
Response,而不是因為等不到另一個 Node 就永遠卡住。

例如 B 聯絡不到 A,但仍然:

Request
 ↓
Node B
 ↓
Response

這就是偏向維持 Availability。


Response 是什麼?

Response 就是 Server 收到 Request 後回給 Client 的結果。

GET /balance

→

{
  "balance": 1000
}

Availability 關心的是:

能不能繼續回應 Request?

它不代表 Response 一定包含最新資料。


Availability 不代表資料一定最新

假設:

A = $500
B = $1,000

Partition:

A ─── X ─── B

B 回:

$1,000

User 有得到 Response,所以 Availability 可能維持了。

但是資料不是最新,因此 Consistency 可能被犧牲。


P:Partition Tolerance

先拆開:

Partition
+
Tolerance

這裡的 Partition 不是 Day 9 的 Database Partition / Sharding。

它是:

Network Partition:兩群 Node 都活著,但彼此暫時不能正常通訊。

Node A ✅
   |
   X  Network Failure
   |
Node B ✅

Tolerance 可以理解成「容忍、承受」。

所以:

Partition Tolerance = Network Partition 發生時,System
仍有明確方式繼續處理,而不是假設 Network 永遠不會出錯。


為什麼 Network Partition 必須考慮?

只要多台 Machine 透過 Network Communication,就可能遇到:

Packet Loss
Network Delay
Router Failure
Data Center Network Problem
Temporary Connectivity Issue

真正的 Distributed System 不能假設:

所有 Node 永遠 100% 可以互相溝通

Packet 與 Packet Loss

Packet 可以先想成:

Network 上傳送的一小包資料。

如果某些 Packet 沒有成功到達目的地,就叫:

Packet Loss

今天不需要深入 Network Protocol,只要知道 Network Communication
本身也可能失敗。


CAP 的問題怎麼產生?

正常:

A = $1,000
B = $1,000

A ←→ B

User 對 A Write:

A = $500

A 通知 B:

B = $500

所以:

A = B = $500

但如果:

A ─── X ─── B

A 收到 Write 後:

A = $500
B = $1,000

這時 B 收到 Read,就必須做選擇。


選擇一:繼續回應

B 用自己手上的 Data 回:

$1,000

優點:

User 得到 Response
Service 繼續提供

也就是 Availability 比較高。

但:

Latest = $500
Returned = $1,000

Consistency 被犧牲。

這就是偏向 AP。


AP 是什麼?

A = Availability
P = Partition Tolerance

可以理解成:

Partition 發生時,System 優先繼續提供
Response,即使部分資料可能暫時不是最新。

可能出現:

Stale Read
Temporary Inconsistency

Temporary Inconsistency 就是:

不同 Node 在一段時間內看到不同 State。

Network 修復後再同步,最後可能重新一致。


選擇二:拒絕不安全的 Operation

B 也可以說:

我聯絡不到 A,
不知道自己的 $1,000 是不是最新,
所以不能安全地把它當成最新資料回傳。

因此:

Request
 ↓
Unavailable / Reject

這樣比較能維持 Consistency,但 User 暫時拿不到結果,因此 Availability
被犧牲。

這就是偏向 CP。


CP 是什麼?

C = Consistency
P = Partition Tolerance

可以理解成:

Partition 發生時,如果無法確認資料符合 Consistency
Requirement,就寧願拒絕或延遲部分
Operation,而不是成功回傳可能不正確的 State。

注意:

CP 不代表整個網站一定 Down。

可能只是某些 Consistency-sensitive Operation 暫時不能成功。

例如:

Homepage → 可以開
Static Image → 可以顯示
Bank Transfer → 暫時不能做

Reject 與 HTTP 503

Reject 就是 Server 不讓某個 Operation 成功完成。

常見 HTTP Status:

503 Service Unavailable

可以理解成:

Service 暫時無法完成這個 Request。

與其亂回不可靠的結果,有些 Operation 寧願暫時失敗。


為什麼 Partition 時不能同時保證 C + A?

Network 正常時:

A ←→ B

可以同時有:

Consistency
+
Availability

真正困難的是 Network Partition:

A ─── X ─── B

兩邊無法知道彼此最新 State。

如果兩邊都繼續接受 Operation:

Availability ↑

但 Data 可能不同:

Consistency ↓

如果要求每個 Operation 都先確認最新 State:

Consistency ↑

但因為無法 Communication:

某些 Request 必須失敗 / 等待
Availability ↓

所以:

Partition 發生時,對需要跨 Node 協調的 Operation,System
無法同時保證 CAP 意義下的 Consistency 與 Availability。


Diverge vs Converge

Diverge:

原本相同的 State 慢慢變得不同。

Original:
A = 100
B = 100

Partition:

A receives +50
B receives -20

A = 150
B = 80

Day 13 的 Converge 則相反:

不同 State
 ↓
Synchronization
 ↓
最後變得一致

所以:

Diverge → 變得不同
Converge → 重新變得一致

為什麼「CAP = 三選二」不夠精確?

常看到:

CAP
Choose Two

很容易誤解成:

設計 System 時
C、A、P 隨便選兩個

例如:

我要 CA,不要 P

但你不能要求 Network:

永遠不要發生 Partition

因此更好的理解是:

當 Network Partition 真正發生時,System 必須決定對該 Operation
更偏向維持 Consistency 還是 Availability。


CA 怎麼理解?

CA:

Consistency
+
Availability

Network 正常時,System 當然可能同時提供 C + A。

如果只有單一 Database:

User
 ↓
Database

沒有多個 Network-separated Copy 要協調,Partition Trade-off
不會以相同方式出現。

但真正跨 Network 的 Distributed System 不能合理假設 Partition
永遠不發生。

因此實務討論 CAP 時,更重要的是:

Partition 發生時
C 還是 A?

Failure 是什麼?

Failure:

System 某一部分沒有按照預期正常工作。

例如:

Server Crash
Network Failure
Disk Failure
Database Unavailable
Timeout

System Design 不能只設計「全部正常」的情況,也要設計 Failure
發生時怎麼辦。


Timeout 是什麼?

A 傳 Request 給 B:

A → B

A 不可能永遠等待。

所以可以設定:

Timeout = 等待超過指定時間,就先認定這次 Operation
沒有在預期時間內完成。

例如:

Timeout = 3 seconds

3 秒沒有 Response:

Timeout Error

但 Timeout 不代表 B 一定掛掉。

可能是:

B Crash
Network 很慢
Response 遺失
B 太忙

所以 Timeout 只代表:

我在期限內沒有收到 Response。


Partial Failure 是什麼?

Distributed System 可能:

Server A ✅
Server B ❌
Server C ✅
Redis ✅
Database ✅
A ↔ C Network ❌

只有部分 Component 失敗。

這叫:

Partial Failure

也就是:

System 某些部分正常、某些部分失敗。


Server Crash vs Network Partition

Server Crash:

Server B ❌

B 本身不能正常工作。

Network Partition:

A ✅ ─── X ─── B ✅

A、B 都可能正常,只是彼此無法 Communication。

這會產生更多不確定性。


CP 的生活例子

假設銀行有:

Branch A
Branch B

Network 斷掉。

A 剛處理:

$1,000 → $100

B 還以為:

$1,000

如果 B 又允許提款 $800,可能造成嚴重問題。

因此某些 Financial Operation 可能:

無法確認最新 State
→ 暫時拒絕 Transaction

這就是 CP 思考方式的直覺。


Transaction 是什麼?

Transaction:

把一組 Database Operation 當成一個完整工作單位處理。

例如 Transfer:

A - $500
B + $500

我們通常不希望:

A 扣成功
B 沒加成功

AP 的生活例子

Social Media Like Count:

Region A → 1001
Region B → 1000

即使 Network Partition,User 可能仍然可以 View / Like Post。

System 不一定要因為 Like Count 暫時不同就停止整個 Service。

Network 修復後再 Synchronize。


Synchronize 是什麼?

Synchronize:

讓不同地方重新交換 Update,使 State 再次接近或達到一致。

A = 1001
B = 1000

Network restored
 ↓
Synchronization
 ↓
A = 1001
B = 1001

Merge 與 Conflict

如果 Partition 期間 A、B 都接受 Write:

A changed data
B also changed data

Network 恢復後可能需要 Merge:

把兩邊的 Change 合併。

但有時會出現 Conflict:

兩個 Node 對同一份 Data 做了互相不相容的 Update。

例如:

Original:
name = Lin

Node A:
name = Alvin

Node B:
name = Wei-Hong

到底要保留哪一個?

這就需要 Conflict Resolution:

System 用什麼規則解決互相衝突的 Update。

所以 AP 也不是免費的。


CP 與 AP 的 Cost

CP:

Partition
 ↓
部分 Operation 暫時失敗
 ↓
User 可能無法完成操作

AP:

Partition
 ↓
兩邊繼續工作
 ↓
State 可能 Diverge
 ↓
Stale Data / Conflict
 ↓
需要 Synchronization / Conflict Resolution

這就是 Trade-off:

得到某個優點,同時接受另一個地方的成本。


Product Catalog、Inventory、Payment

Product Description 晚幾秒更新,Business Impact
可能很小,因此可能偏向繼續提供 Read。

Inventory Checkout 就不同:

Stock = 1

Region A thinks 1
Region B thinks 1

兩邊都賣:

Order A Success
Order B Success

可能 Oversell。

Payment 更敏感。

如果:

Payment Request
 ↓
Timeout

Client 不知道到底有沒有成功。

直接 Retry 又可能造成 Duplicate Request / Double Charge。

Double Charge:

同一筆原本只應扣一次的 Payment,被重複扣款。

這會連回 Day 11 的:

Idempotency

所以 System Design 的概念不是獨立背誦,而是彼此相連。


同一個 System 可以有 CP-like 和 AP-like Feature 嗎?

可以。

例如 E-commerce:

Recommendation
→ Stale 幾秒通常可以接受

View Count
→ Eventual Consistency 可以接受

Inventory Checkout
→ Consistency Requirement 更高

Payment
→ 對 Incorrect / Duplicate State 非常敏感

因此更好的問題不是:

「整個 System 是 CP 還是 AP?」

而是:

這一份 Data / 這一個 Operation,在 Partition 時應該怎麼做?


Region 與 Multi-Region

Region 可以理解成:

Cloud Provider 在某個地理區域提供的一組 Infrastructure。

例如概念上:

US Region
Europe Region
Asia Region

Multi-Region:

System 部署在多個 Region。

US ←→ Europe ←→ Asia

好處可能包括:

Closer to Users
Lower Latency
Better Failure Isolation

但跨 Region Network 也讓 Replication Lag、Network Failure、Consistency
更重要。


Split Brain 是什麼?

Split Brain 可以想成:

原本一個 System
 ↓ Network Partition
分成兩群

如果兩邊都認為:

「我可以接受主要 Write。」

就可能同時修改同一份 Data:

Group A     Group B
Writes      Writes
   \          /
    Network X

最後 Data 可能 Diverge。

叫 Split Brain,是因為像原本「一個大腦」分成兩個,各自認為自己知道正確
State。


Quorum 是什麼?

Quorum 可以理解成:

要有足夠多成員同意,才能做正式決定。

生活例子:

5 人開會
至少 3 人到場
才能做決定

這個「至少 3 人」就是一種 Quorum Requirement。

Distributed System 也可能要求:

5 Nodes
至少 3 Nodes 能確認

才能做某些重要 Operation。


Majority 是什麼?

Majority:

多數

5 Nodes 的 Majority:

3

Partition:

Group A = 3 Nodes
Group B = 2 Nodes

某些 System 可以讓 3-Node Group 繼續做需要 Majority 的 Operation,而
2-Node Group 不能。

這可以降低兩邊同時認為自己有權做重要 Write 的風險。

注意:

Quorum 不是 CAP 本身的一部分。

它是 Distributed System 中可能用來做 Coordination / Decision 的概念。


Leader 與 Follower

某些 Distributed System 會有:

Node A → Leader
Node B → Follower
Node C → Follower

Leader:

目前負責某些主要決策或 Write Coordination 的 Node。

Follower:

跟隨 Leader、接收 Update 的其他 Node。

例如:

Client
 ↓
Leader
 ↓
Replicate
 ↓
Followers

Leader Election 是什麼?

如果:

Leader ❌

System 可能需要從其他 Node 中選出新的 Leader。

這個過程叫:

Leader Election

Election 就是「選舉」。


Consensus 是什麼?

Consensus 中文常翻成「共識」。

可以先理解成:

多個 Node 按照一套 Protocol,對某個重要結果達成一致決定。

例如:

誰是 Leader?
哪個 Update 應被接受?
Operation 順序是什麼?

真正的 Distributed Consensus 很深,今天不用深入 Algorithm。

只要知道:

它是在處理多個 Node 如何在 Failure 與 Network
不可靠時,仍對重要事情達成一致。


Protocol 是什麼?

Protocol:

參與者事先約定的一套溝通規則。

像紅綠燈:

Red → Stop
Green → Go

Distributed System 也需要規則:

收到什麼 Message 要做什麼?
Timeout 後做什麼?
誰可以成為 Leader?

CAP 和 Consensus 不是同一件事:

CAP
→ 描述 Partition 下 C / A 的限制

Consensus
→ 多個 Node 如何對重要 Decision 達成一致

台積 IT 面試情境:兩個 Data Center 斷線

Data Center A
Data Center B

A ─── X ─── B

兩邊都收到 Request。

不要馬上回答:

CP!

或:

AP!

先問:

這是什麼 Operation?

Read Product Description?
Like Post?
Update Inventory?
Transfer Money?

再問:

Stale Data 可以接受嗎?
拒絕 Request 可以接受嗎?
兩邊都 Write 會怎樣?
之後 Conflict 怎麼處理?

最後才決定 Partition 時的 Behavior。


CAP 不是所有 Failure 的答案

CAP 特別討論:

Network Partition

它不是說:

CPU 太慢
Disk 滿
Code Bug

全部都是 CAP Problem。

也不是 Performance Theorem。

不要說:

CP 一定慢
AP 一定快

Performance 還受 Network、Hardware、Database、Algorithm、Caching、Load
等很多因素影響。


CAP 也不是 SQL vs NoSQL

不要背:

SQL = CP
NoSQL = AP

這太簡化。

真正 Behavior 取決於:

Architecture
Replication Model
Configuration
Read / Write Policy
Failure Condition

同一個 Product 在不同 Configuration 下,也可能有不同 Trade-off。


CAP 的正確思考流程

1. 有沒有 Network Partition?

2. 哪些 Node 不能互相 Communication?

3. Partition 期間還允許 Read 嗎?

4. Read 可能 Stale 嗎?

5. Partition 期間還允許 Write 嗎?

6. 兩邊都 Write,Data 會 Diverge 嗎?

7. Network 恢復後需要 Merge / Conflict Resolution 嗎?

8. 如果拒絕 Request,Business Impact 是什麼?

9. 這個 Operation 更不能接受:
   Stale / Conflicting Data
   還是 Temporary Unavailability?

最後才描述:

CP-like behavior
or
AP-like behavior

一張圖理解 CAP

正常:

        Network OK

Node A ←────────────→ Node B

Data = 100            Data = 100

Consistency ✅
Availability ✅

Partition:

        Network Broken

Node A ─────── X ─────── Node B

Data = 200              Data = 100

Option 1:

Node B continues serving
→ Availability
→ Possibly stale data
→ AP-like

Option 2:

Node B refuses operation
until state can be verified
→ Consistency
→ Temporary unavailability
→ CP-like

台積 IT 面試準備 Checkpoint

1. Theorem 是什麼?
2. CAP 分別代表什麼?
3. CAP 的 Consistency 是什麼?
4. View / Node 是什麼?
5. CAP 的 Availability 是什麼?
6. Availability 是否代表 Data 最新?
7. Partition Tolerance 是什麼?
8. Network Partition 是什麼?
9. Database Partition vs Network Partition?
10. Tolerance 是什麼?
11. Packet / Packet Loss 是什麼?
12. 為什麼 Distributed System 要考慮 Network Failure?
13. Partition 時為什麼 C 和 A 會衝突?
14. AP 是什麼?Cost 是什麼?
15. Temporary Inconsistency 是什麼?
16. CP 是什麼?Cost 是什麼?
17. CP 是否代表整個 System Down?
18. HTTP 503 是什麼?
19. 為什麼 CAP 三選二不夠精確?
20. CA 應該怎麼理解?
21. Failure / Timeout 是什麼?
22. Timeout 是否代表對方一定 Crash?
23. Partial Failure 是什麼?
24. Server Crash vs Network Partition?
25. Diverge vs Converge?
26. Synchronize / Merge 是什麼?
27. Conflict / Conflict Resolution 是什麼?
28. Product Catalog 在 Partition 時怎麼想?
29. Inventory 呢?
30. Payment 呢?
31. Double Charge 是什麼?
32. 同一 System 能有 CP-like 和 AP-like Operation 嗎?
33. Region / Multi-Region 是什麼?
34. Split Brain 是什麼?
35. Quorum / Majority 是什麼?
36. Quorum 和 CAP 是同一件事嗎?
37. Leader / Follower 是什麼?
38. Leader Election 是什麼?
39. Consensus 是什麼?
40. Protocol 是什麼?
41. Consensus vs CAP?
42. Timeout 為什麼連到 Retry?
43. Retry 為什麼又連到 Idempotency?
44. CAP 是否適用所有 Failure?
45. CAP 是否是在比較 Performance?
46. 可以直接說 SQL = CP、NoSQL = AP 嗎?
47. 面試遇到 CAP 問題應先問什麼?

今天學到了什麼?

CAP:

C = Consistency
A = Availability
P = Partition Tolerance

真正重要的是:

正常:
Node A ←→ Node B

→ Consistency + Availability 都可以維持

困難發生在:

Node A ─── X ─── Node B

Node 無法確認彼此最新 State。

此時:

繼續提供 Service
→ Availability
→ 可能暫時不一致
→ AP-like

或:

拒絕無法安全確認的 Operation
→ Consistency
→ 部分 Service 暫時不可用
→ CP-like

所以比起:

CAP = Pick Two

更好的理解是:

當 Network Partition 發生時,這個 Operation
更不能接受資料不一致,還是更不能接受暫時無法提供服務?

而且不同 Data / Operation 的答案可以不同。


下一篇

今天一直出現:

Server Failure
Network Failure
Timeout
Partial Failure

大型 System 不能假設所有 Component 永遠正常。

如果 Backend 掛掉怎麼辦?

Database Primary 掛掉呢?

External API 掛掉時,要一直 Retry 嗎?

Retry 太多會不會反而把快掛掉的 Service 打得更嚴重?

下一篇:

Day 15|Reliability:Server 掛掉之後,System 為什麼還能繼續運作?

會從零解釋:

Reliability
Failure
Fault
Fault Tolerance
Redundancy
Failover
Retry
Timeout
Exponential Backoff
Circuit Breaker
Health Check
Single Point of Failure

再把 Load Balancer、Database Replication、Message Queue、Timeout、Retry
串成一個真正能面對 Failure 的 System。


上一篇
# Day 13|Consistency:為什麼 Distributed System 有時會讀到舊資料?
下一篇
# Day 15|Reliability:Server 掛掉之後,System 為什麼還能繼續運作?
系列文
30 天從 Full-Stack Engineer 進化到 System Design:從 0 設計可支撐百萬使用者的系統 共 15 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言