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 中文通常翻成「定理」。
可以先理解成:
經過數學或邏輯方式證明成立的一個結論。
CAP Theorem 不是 Database Product,也不是 Design Pattern,而是在描述
Distributed System 在特定情況下受到的限制。
C = Consistency
A = Availability
P = Partition Tolerance
重點不是背縮寫,而是理解每個字真正代表什麼。
Day 13 已經學過 Consistency。
在 CAP 的情境,可以先理解成:
每次成功的 Read,都像是在讀同一份最新資料。
例如:
Initial:
A = $1,000
B = $1,000
Write to A:
A = $500
如果要維持這種 Consistency,B 就不能再成功把舊的 $1,000 當成最新 State
回傳。
這裡的 View 不是 Frontend UI。
它代表:
某個 Node 目前看到 / 知道的資料狀態。
例如:
A's View → $500
B's View → $1,000
代表兩邊對同一份 Data 的 View 不一樣。
Node:
Distributed System 中參與工作的其中一台 Machine、Server 或
Instance。
例如:
Database Node A
Database Node B
Database Node C
CAP 討論的就是多個 Node 透過 Network Communication 工作時的問題。
一般來說,Availability 可以理解成:
System 在 User 需要時能不能正常提供 Service。
在 CAP 的情境,要再精確一點:
一個仍能正常工作的 Node 收到 Request 後,要能在有限時間內給出
Response,而不是因為等不到另一個 Node 就永遠卡住。
例如 B 聯絡不到 A,但仍然:
Request
↓
Node B
↓
Response
這就是偏向維持 Availability。
Response 就是 Server 收到 Request 後回給 Client 的結果。
GET /balance
→
{
"balance": 1000
}
Availability 關心的是:
能不能繼續回應 Request?
它不代表 Response 一定包含最新資料。
假設:
A = $500
B = $1,000
Partition:
A ─── X ─── B
B 回:
$1,000
User 有得到 Response,所以 Availability 可能維持了。
但是資料不是最新,因此 Consistency 可能被犧牲。
先拆開:
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 永遠不會出錯。
只要多台 Machine 透過 Network Communication,就可能遇到:
Packet Loss
Network Delay
Router Failure
Data Center Network Problem
Temporary Connectivity Issue
真正的 Distributed System 不能假設:
所有 Node 永遠 100% 可以互相溝通
Packet 可以先想成:
Network 上傳送的一小包資料。
如果某些 Packet 沒有成功到達目的地,就叫:
Packet Loss
今天不需要深入 Network Protocol,只要知道 Network Communication
本身也可能失敗。
正常:
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。
A = Availability
P = Partition Tolerance
可以理解成:
Partition 發生時,System 優先繼續提供
Response,即使部分資料可能暫時不是最新。
可能出現:
Stale Read
Temporary Inconsistency
Temporary Inconsistency 就是:
不同 Node 在一段時間內看到不同 State。
Network 修復後再同步,最後可能重新一致。
B 也可以說:
我聯絡不到 A,
不知道自己的 $1,000 是不是最新,
所以不能安全地把它當成最新資料回傳。
因此:
Request
↓
Unavailable / Reject
這樣比較能維持 Consistency,但 User 暫時拿不到結果,因此 Availability
被犧牲。
這就是偏向 CP。
C = Consistency
P = Partition Tolerance
可以理解成:
Partition 發生時,如果無法確認資料符合 Consistency
Requirement,就寧願拒絕或延遲部分
Operation,而不是成功回傳可能不正確的 State。
注意:
CP 不代表整個網站一定 Down。
可能只是某些 Consistency-sensitive Operation 暫時不能成功。
例如:
Homepage → 可以開
Static Image → 可以顯示
Bank Transfer → 暫時不能做
Reject 就是 Server 不讓某個 Operation 成功完成。
常見 HTTP Status:
503 Service Unavailable
可以理解成:
Service 暫時無法完成這個 Request。
與其亂回不可靠的結果,有些 Operation 寧願暫時失敗。
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:
原本相同的 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
Choose Two
很容易誤解成:
設計 System 時
C、A、P 隨便選兩個
例如:
我要 CA,不要 P
但你不能要求 Network:
永遠不要發生 Partition
因此更好的理解是:
當 Network Partition 真正發生時,System 必須決定對該 Operation
更偏向維持 Consistency 還是 Availability。
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:
System 某一部分沒有按照預期正常工作。
例如:
Server Crash
Network Failure
Disk Failure
Database Unavailable
Timeout
System Design 不能只設計「全部正常」的情況,也要設計 Failure
發生時怎麼辦。
A 傳 Request 給 B:
A → B
A 不可能永遠等待。
所以可以設定:
Timeout = 等待超過指定時間,就先認定這次 Operation
沒有在預期時間內完成。
例如:
Timeout = 3 seconds
3 秒沒有 Response:
Timeout Error
但 Timeout 不代表 B 一定掛掉。
可能是:
B Crash
Network 很慢
Response 遺失
B 太忙
所以 Timeout 只代表:
我在期限內沒有收到 Response。
Distributed System 可能:
Server A ✅
Server B ❌
Server C ✅
Redis ✅
Database ✅
A ↔ C Network ❌
只有部分 Component 失敗。
這叫:
Partial Failure
也就是:
System 某些部分正常、某些部分失敗。
Server Crash:
Server B ❌
B 本身不能正常工作。
Network Partition:
A ✅ ─── X ─── B ✅
A、B 都可能正常,只是彼此無法 Communication。
這會產生更多不確定性。
假設銀行有:
Branch A
Branch B
Network 斷掉。
A 剛處理:
$1,000 → $100
B 還以為:
$1,000
如果 B 又允許提款 $800,可能造成嚴重問題。
因此某些 Financial Operation 可能:
無法確認最新 State
→ 暫時拒絕 Transaction
這就是 CP 思考方式的直覺。
Transaction:
把一組 Database Operation 當成一個完整工作單位處理。
例如 Transfer:
A - $500
B + $500
我們通常不希望:
A 扣成功
B 沒加成功
Social Media Like Count:
Region A → 1001
Region B → 1000
即使 Network Partition,User 可能仍然可以 View / Like Post。
System 不一定要因為 Like Count 暫時不同就停止整個 Service。
Network 修復後再 Synchronize。
Synchronize:
讓不同地方重新交換 Update,使 State 再次接近或達到一致。
A = 1001
B = 1000
Network restored
↓
Synchronization
↓
A = 1001
B = 1001
如果 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:
Partition
↓
部分 Operation 暫時失敗
↓
User 可能無法完成操作
AP:
Partition
↓
兩邊繼續工作
↓
State 可能 Diverge
↓
Stale Data / Conflict
↓
需要 Synchronization / Conflict Resolution
這就是 Trade-off:
得到某個優點,同時接受另一個地方的成本。
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 的概念不是獨立背誦,而是彼此相連。
可以。
例如 E-commerce:
Recommendation
→ Stale 幾秒通常可以接受
View Count
→ Eventual Consistency 可以接受
Inventory Checkout
→ Consistency Requirement 更高
Payment
→ 對 Incorrect / Duplicate State 非常敏感
因此更好的問題不是:
「整個 System 是 CP 還是 AP?」
而是:
這一份 Data / 這一個 Operation,在 Partition 時應該怎麼做?
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 可以想成:
原本一個 System
↓ Network Partition
分成兩群
如果兩邊都認為:
「我可以接受主要 Write。」
就可能同時修改同一份 Data:
Group A Group B
Writes Writes
\ /
Network X
最後 Data 可能 Diverge。
叫 Split Brain,是因為像原本「一個大腦」分成兩個,各自認為自己知道正確
State。
Quorum 可以理解成:
要有足夠多成員同意,才能做正式決定。
生活例子:
5 人開會
至少 3 人到場
才能做決定
這個「至少 3 人」就是一種 Quorum Requirement。
Distributed System 也可能要求:
5 Nodes
至少 3 Nodes 能確認
才能做某些重要 Operation。
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 的概念。
某些 Distributed System 會有:
Node A → Leader
Node B → Follower
Node C → Follower
Leader:
目前負責某些主要決策或 Write Coordination 的 Node。
Follower:
跟隨 Leader、接收 Update 的其他 Node。
例如:
Client
↓
Leader
↓
Replicate
↓
Followers
如果:
Leader ❌
System 可能需要從其他 Node 中選出新的 Leader。
這個過程叫:
Leader Election
Election 就是「選舉」。
Consensus 中文常翻成「共識」。
可以先理解成:
多個 Node 按照一套 Protocol,對某個重要結果達成一致決定。
例如:
誰是 Leader?
哪個 Update 應被接受?
Operation 順序是什麼?
真正的 Distributed Consensus 很深,今天不用深入 Algorithm。
只要知道:
它是在處理多個 Node 如何在 Failure 與 Network
不可靠時,仍對重要事情達成一致。
Protocol:
參與者事先約定的一套溝通規則。
像紅綠燈:
Red → Stop
Green → Go
Distributed System 也需要規則:
收到什麼 Message 要做什麼?
Timeout 後做什麼?
誰可以成為 Leader?
CAP 和 Consensus 不是同一件事:
CAP
→ 描述 Partition 下 C / A 的限制
Consensus
→ 多個 Node 如何對重要 Decision 達成一致
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 特別討論:
Network Partition
它不是說:
CPU 太慢
Disk 滿
Code Bug
全部都是 CAP Problem。
也不是 Performance Theorem。
不要說:
CP 一定慢
AP 一定快
Performance 還受 Network、Hardware、Database、Algorithm、Caching、Load
等很多因素影響。
不要背:
SQL = CP
NoSQL = AP
這太簡化。
真正 Behavior 取決於:
Architecture
Replication Model
Configuration
Read / Write Policy
Failure Condition
同一個 Product 在不同 Configuration 下,也可能有不同 Trade-off。
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
正常:
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
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。