本篇目標:從零理解 Reliability,以及 System 如何面對 Failure。
**Reliability(可靠性)**可以簡單理解成:
System 能不能在一段時間內,持續正確完成它應該做的工作。
Reliability 不代表所有 Server 永遠不壞。真正的想法是:
Failure WILL happen
↓
Design for Failure
例如:
Backend #1 ❌
Backend #2 ✅
Backend #3 ✅
如果 #1 掛掉後,其他 Backend 仍能處理 Request,整個 Service
不一定跟著掛掉。
Component 是 System 裡負責某一類工作的組成部分,例如:
Load Balancer
Backend Server
Redis
Database
Message Queue
External API
大型 System 通常由很多 Component 一起完成工作。
Fault 可以理解成「造成問題的異常原因」。
例如:
Disk Problem
Memory Error
Network Problem
Software Bug
Wrong Configuration
Failure 則是:
System 或 Component 最後沒有完成它應該提供的工作。
例如:
Disk Fault
↓
Database 無法讀資料
↓
Database Failure
最簡單記:
Fault → 問題的來源
Failure → 沒有完成預期工作
Fault 不一定會讓 User 感受到 Failure。如果 System 有替代方案,Fault
發生後 Service 仍可能繼續。
Tolerance 就是「容忍、承受」。
所以 Fault Tolerance 是:
某個 Component 出問題時,System 仍然可以繼續提供 Service 的能力。
例如:
User
↓
Load Balancer
├── Backend #1 ❌
├── Backend #2 ✅
└── Backend #3 ✅
Load Balancer 不再把新 Request 送給 #1。
這就是 Fault Tolerance 的一個例子。
**Redundancy(冗餘)**可以簡單理解成:
不要只有唯一一份,而是準備額外的 Component 或 Copy。
只有一台 Backend:
User → Backend ❌
Service 可能直接 Down。
有多台:
┌→ Backend #1 ❌
User → LB ├→ Backend #2 ✅
└→ Backend #3 ✅
仍然有替代 Server。
Redundancy 也可以出現在:
Multiple Load Balancers
Multiple Backend Servers
Database Replicas
Multiple Availability Zones
Single Point of Failure 常縮寫成:
SPOF
意思是:
某個 Component 一旦壞掉,就會讓整個 System 或重要 Service 無法運作。
例如:
User
↓
Only One Load Balancer
↓
Backend #1
Backend #2
Backend #3
即使 Backend 有三台,唯一的 Load Balancer 掛掉,User 還是進不去。
所以:
解決一個 SPOF,不代表整個 Architecture 已經沒有其他 SPOF。
Database 也可能成為 SPOF。
Day 8 學過:
Primary DB
├── Replica #1
└── Replica #2
如果:
Primary ❌
Replica #1 ✅
System 可能把 Replica 提升成新的 Primary。
這叫:
Failover
主要 Component 壞掉後,把工作切換到備用 Component。
Primary ❌
↓
Promote Replica
↓
New Primary
Promote 就是把原本的備用角色提升成主要角色。
Manual Failover:
Engineer 發現問題
↓
人工切換
Automatic Failover:
System detects failure
↓
Automatically promotes backup
↓
Traffic switches
Automatic Failover 通常恢復較快,但 Architecture 也更複雜。
Failover 前,System 要先判斷:
誰出問題了?
這叫 Failure Detection。
但是:
No Response
不一定代表 Server 已經死亡。
也可能是:
Network Slow
Network Partition
Server Busy
所以常搭配:
Health Check
Timeout
Heartbeat
Health Check:
定期確認 Component 是否仍能正常提供 Service。
例如:
Load Balancer
↓
GET /health
↓
Backend
Backend 回:
200 OK
代表看起來 Healthy。
連續 Timeout:
Timeout
Timeout
Timeout
可能被標記成 Unhealthy,Load Balancer 停止把新 Request 送給它。
注意:
Process 還活著
≠
Service 一定 Healthy
例如 Backend Process 還在,但 Database Connection
全壞了,它可能已無法真正服務 User。
Heartbeat(心跳):
Component 定期送出小訊號,表示「我還活著」。
Server
↓ every few seconds
Heartbeat
↓
Coordinator
如果很久沒收到 Heartbeat,Server 可能有問題。
但沒收到 Heartbeat也不代表 Server 100% 死亡,也可能只是 Network
Problem。
Retry 就是:
第一次 Operation 失敗後,再嘗試一次。
Attempt #1 → Timeout
Attempt #2 → Success
Retry 對短暫 Failure 很有幫助。
Transient Failure:
短暫出現,之後可能自己恢復的 Failure。
例如:
Temporary Network Problem
Temporary Overload
Brief DB Connection Failure
Retry 可能有效。
Permanent Failure:
不會因為立刻再試一次就恢復的問題。
例如:
Wrong Password
Invalid API Key
Invalid Request
File Does Not Exist
Retry 100 次通常也不會成功。
所以:
不是所有 Error 都應該 Retry。
假設 Service Capacity:
1,000 req/s
現在:
1,200 req/s
開始 Timeout。
如果所有 Client 都立刻 Retry:
Original = 1,200
Retry = 1,200
Total = 2,400 req/s
Service 更忙,產生更多 Failure,再產生更多 Retry。
這叫 Retry Storm:
大量 Client 因 Failure 同時不停 Retry,反而把已經有問題的 Service
壓得更嚴重。
Backoff:
Retry 前先等待一段時間。
不要:
Fail → Retry immediately
Fail → Retry immediately
可以:
Fail
↓
Wait 1 sec
↓
Retry
↓
Wait 2 sec
↓
Retry
↓
Wait 4 sec
如果等待時間:
1 → 2 → 4 → 8 → 16
按照倍數增加,就叫 Exponential Backoff。
目的:
Give Service Time to Recover
Reduce Retry Traffic
Avoid Retry Storm
如果 10,000 Clients 同時 Failure,而且全部都等相同時間:
Wait 4 sec
4 秒後又可能同時 Retry。
所以加入 Jitter:
在等待時間加入一些隨機差異,讓 Retry 分散。
Client A → 3.7 sec
Client B → 4.2 sec
Client C → 4.8 sec
Timeout:
等待超過指定時間,就停止繼續等這次 Operation。
例如:
Backend
↓
External API
Timeout = 3 sec
3 秒沒 Response:
Timeout Error
如果沒有 Timeout,Request 可能一直占用 System Resource。
Resource:
Computer / System 可以使用,但數量有限的東西。
例如:
CPU
Memory
Thread
Network Connection
Database Connection
Disk
等待也是有成本的。
先用簡單版本理解:
Thread 是 Program 執行工作的其中一條執行路徑。
大量 Request 卡住:
Thread #1 → Waiting
Thread #2 → Waiting
Thread #3 → Waiting
可用 Thread 可能被耗盡。
Connection:
兩個 Component 之間建立的一條 Communication 關係。
例如:
Backend
↓
Database Connection
↓
PostgreSQL
Connection Pool:
Application 管理的一組可重複使用 Connections。
Pool
├── Connection #1
├── Connection #2
...
└── Connection #20
Request:
Borrow
↓
Query
↓
Return
如果全部 Connection 都卡住,新 Request 可能拿不到 Connection。
假設:
Database Slow
↓
Backend Requests Waiting
↓
Threads / Connections Occupied
↓
Backend Slow
↓
Clients Retry
↓
More Traffic
↓
Database Even Slower
一個 Component 的問題一路擴散:
Cascading Failure
就像瀑布一樣,一層影響下一層。
Circuit Breaker 原本是電路的斷路器。
Software 裡:
Order Service
↓
Payment Service
Payment 已大量 Failure。
如果還一直:
Call → Fail
Call → Fail
Call → Fail
只會浪費 Resource。
Circuit Breaker 可以:
Failure 太多
↓
暫停呼叫
↓
Fail Fast
讓 Downstream 有時間恢復。
Client
↓
Order Service
↓
Payment Service
對 Order Service:
Payment Service = Downstream
也就是它接下來呼叫 / 依賴的 Service。
對 Payment Service:
Order Service = Upstream
也就是呼叫它的上游 Service。
Circuit Breaker [Closed]
↓
Request 可以通過
Failure 太多:
Circuit Breaker [Open]
X
Downstream
Request 不再真的 Call Downstream,而是 Fail Fast。
Fail Fast:
已經知道成功機率很低,就快速回 Failure,不浪費大量等待時間與
Resource。
等待一段時間後:
Open
↓
Half-Open
先放少量 Test Request。
成功:
Half-Open → Closed
失敗:
Half-Open → Open
Circuit Breaker 不是修好 Downstream,而是避免 Failure 繼續擴散。
Bulkhead 原本是船的水密隔艙。
Software 裡:
把不同工作使用的 Resource 隔離,避免一個功能把全部 Resource 用光。
例如 100 Threads:
Payment → 30
Product → 40
User → 30
Payment 全卡住,Product / User 還有自己的 Resource。
Recommendation Service:
❌
選擇 A:
整個 Product Page Error
選擇 B:
Product Page 正常
Recommendation 暫時不顯示
B 就叫 Graceful Degradation:
部分功能失敗時,降低部分功能,而不是讓整個 System 一起失敗。
Core Feature:
User 使用 System 最主要、不能輕易缺少的功能。
例如:
Checkout
Payment
Non-critical Feature:
暫時沒有也不會讓核心流程完全不能用。
例如:
Recommendation
Analytics
Fallback:
主要方法失敗時,使用比較簡單的替代方案。
Personalized Recommendation ❌
↓
Fallback
↓
Popular Products
Dependency:
一個 Component 正常完成工作時,需要依賴的另一個 Component / Resource。
Order Service
↓
Payment Service
Payment 是 Order 的 Dependency。
Critical Dependency:
它失敗後,核心 Operation 就無法安全完成。
Payment 對 Checkout 可能是 Critical Dependency;Recommendation
通常不是。
Redundancy:
準備額外 Component / Resource。
Replication:
把 Data 複製成多份。
Replication 可以是實現 Redundancy 的方式之一。
Backup:
保存歷史 Data Copy,主要用於 Restore。
例如:
DELETE FROM users;
Replication 可能連 Delete 都同步出去。
Replica 不一定能救你,但昨天的 Backup 可能可以 Restore。
所以:
Redundancy / Replication 不等於 Backup。
High Availability(HA):
透過 Architecture Design,讓 Service 在 Component Failure
時仍盡量保持可使用。
常見方法:
Redundancy
Load Balancing
Replication
Failover
Health Check
Multi-AZ
Reliability:
System 能不能持續正確完成工作。
Availability:
User 需要使用時,Service 是否可用。
例如:
每小時 Crash 一次
但每次 1 秒恢復
Availability 可能仍很高,因為 Downtime 很短。
但 Reliability 不一定好,因為 Failure 很頻繁。
Downtime:
Service 無法正常提供使用的時間。
10:00 Down
10:05 Recovered
Downtime = 5 minutes。
Recovery:
Failure 發生後,System 恢復正常 Service 的過程。
Primary ❌
↓
Failover
↓
Replica promoted
↓
Service restored
MTBF:
Mean Time Between Failures
意思:
平均多久發生一次 Failure。
MTBF 越長
→ Failure 越不頻繁
MTTR 常表示:
Mean Time To Recovery
意思:
Failure 後平均多久恢復 Service。
Reliability Engineering 通常希望:
Longer MTBF
+
Shorter MTTR
也就是:
少壞一點
+
壞了快點恢復
Availability Zone(AZ):
Cloud Region 裡彼此相對獨立的一組 Data Center Infrastructure。
概念:
Region
├── AZ-A
├── AZ-B
└── AZ-C
Multi-AZ:
把 System 部署到多個 AZ。
Load Balancer
/ ↓ ↓
AZ-A AZ-B
Backend Backend
AZ-A Failure 時,AZ-B 還可能提供 Service。
不要和 Multi-Region 混淆:
Multi-AZ
→ 同一 Region 的多個 AZ
Multi-Region
→ 多個不同地理 Region
這三個常一起想:
Timeout
→ 不要永遠等待
Retry
→ Transient Failure 可以再試
Backoff + Jitter
→ 不要瘋狂同時 Retry
Circuit Breaker
→ Downstream 明顯失敗時暫停大量 Call
完整流程:
Call Payment
↓
Timeout
↓
Backoff
↓
Retry
↓
Repeated Failures
↓
Circuit Breaker Open
↓
Fail Fast
↓
Wait
↓
Half-Open
↓
Test Request
↓
Success
↓
Closed
第一次 Payment 可能其實成功:
Charge $100
↓
Payment Success
↓
Response Lost
Caller 只看到 Timeout。
Retry:
Charge $100 again
可能造成 Double Charge。
所以某些 Write Operation 的 Retry 需要 Idempotency:
同一個 Operation 重複執行,不應產生不希望的重複 Side Effect。
例如:
Idempotency Key:
payment:order:123
已處理過同一 Key:
Return previous result
而不是再扣一次。
Side Effect:
Operation 除了回傳結果之外,對 System State 造成的改變。
例如:
Charge Card → Money deducted
Send Email → Email sent
Create Order → New row created
Retry 導致 Money 扣兩次,就是不希望的 Duplicate Side Effect。
Isolate 就是「隔離」。
Failure Isolation:
把 Failure 的影響限制在較小範圍,不讓它擴散到整個 System。
例如:
Bulkhead
Circuit Breaker
Separate Resource Pools
都可以幫助 Failure Isolation。
Failure Domain:
某一個 Failure 發生時,可能一起受到影響的一組 Component。
例如:
Backend #1
Backend #2
Backend #3
看似有三台,但如果全部跑在同一台 Physical Machine:
Physical Machine ❌
↓
#1 ❌
#2 ❌
#3 ❌
它們其實共享同一 Failure Domain。
同樣,如果所有 Server 都在同一個 AZ,AZ Failure 時可能全部受影響。
所以真正的 Redundancy 不只是:
數量多
還要問:
這些 Copy 是否真的獨立?
User
↓
Load Balancer
/ ↓ ↓
Backend #1 Backend #2
✅ ✅
\ /
↓ ↓
Redis / Cache
↓
Database Primary
/ ↓ ↓
Replica #1 Replica #2
Backend
↓
Timeout
↓
Circuit Breaker
↓
External Service
Backend 掛掉:
Health Check
↓
Remove Unhealthy Backend
↓
Route to Healthy Backend
Database Primary 掛掉:
Failover
↓
Promote Replica
External Service 掛掉:
Timeout
Retry + Backoff + Jitter
Circuit Breaker
Fallback
Load Balancer
↓
Health Check
↓
Detect Unhealthy Backend
↓
Stop Routing to It
↓
Other Backends Continue
關鍵:
Redundancy
Health Check
Fault Tolerance
Primary ❌
Replica ✅
↓
Failure Detection
↓
Promote Replica
↓
New Primary
還要考慮:
Replication Lag
Data Loss Risk
Split Brain
Leader Election
Timeout
↓
Retry only when appropriate
↓
Exponential Backoff
↓
Jitter
↓
Circuit Breaker
↓
Fallback if possible
Permanent Error,例如 Invalid API Key,不應一直 Retry。
如果它不是 Critical Dependency:
Recommendation ❌
↓
Product Page continues
可以 Hide Recommendation,或 Fallback to Popular Products。
這就是 Graceful Degradation。
看到:
Retry
Circuit Breaker
Bulkhead
Fallback
Replication
Multi-AZ
不要直接全部加入。
每個 Pattern 都有 Cost:
More Complexity
More Infrastructure
More Monitoring
More Testing
More Operational Cost
仍然要:
Problem
↓
Requirement
↓
Solution
↓
Trade-off
1. Reliability 是什麼?
2. Reliability 是否代表永遠不壞?
3. Component 是什麼?
4. Fault vs Failure?
5. Fault Tolerance 是什麼?
6. Redundancy 是什麼?
7. SPOF 是什麼?
8. Load Balancer / Database 可以是 SPOF 嗎?
9. Failover 是什麼?
10. Promote Replica 是什麼?
11. Manual vs Automatic Failover?
12. Failure Detection 是什麼?
13. Health Check 是什麼?
14. Heartbeat 是什麼?
15. Retry 是什麼?
16. Transient vs Permanent Failure?
17. Retry Storm 是什麼?
18. Backoff / Exponential Backoff 是什麼?
19. Jitter 是什麼?
20. Timeout 是什麼?
21. Resource / Thread 是什麼?
22. Connection / Connection Pool 是什麼?
23. Cascading Failure 是什麼?
24. Circuit Breaker 是什麼?
25. Upstream / Downstream 是什麼?
26. Closed / Open / Half-Open 是什麼?
27. Fail Fast 是什麼?
28. Bulkhead 是什麼?
29. Graceful Degradation 是什麼?
30. Fallback 是什麼?
31. Dependency / Critical Dependency 是什麼?
32. Redundancy vs Replication vs Backup?
33. High Availability 是什麼?
34. Reliability vs Availability?
35. Downtime / Recovery 是什麼?
36. MTBF / MTTR 是什麼?
37. Availability Zone 是什麼?
38. Multi-AZ vs Multi-Region?
39. Retry + Timeout + Circuit Breaker 如何一起工作?
40. Retry 為什麼需要 Idempotency?
41. Side Effect 是什麼?
42. Failure Isolation 是什麼?
43. Failure Domain 是什麼?
44. 為什麼有三台 Server 不一定代表真正有良好 Redundancy?
Reliability 的核心不是:
讓所有東西永遠不壞
而是:
接受 Failure 一定會發生,並讓 System
有能力偵測、隔離、承受與恢復。
重要關係:
Fault
↓
may cause
↓
Failure
好的 Architecture:
Failure
↓
Detection
↓
Isolation
↓
Failover / Retry / Fallback
↓
Recovery
最重要的一句:
Reliable System 不是不會 Failure 的 System,而是 Failure
發生時,不會輕易讓整個 System 一起倒下,而且能快速恢復的 System。
現在我們知道:
Server 可能掛掉
Database 可能掛掉
Network 可能 Timeout
External Service 可能 Failure
下一個問題:
System 出問題時,我們怎麼知道到底是哪裡壞掉?
如果 User 說:
網站今天很慢
Engineer 要怎麼知道:
Backend 慢?
Database 慢?
Redis 慢?
External API 慢?
Traffic 增加?
Error Rate 上升?
下一篇:
Day 16|Observability:System 出問題時,我們到底怎麼知道哪裡壞了?
會從零解釋:
Observability
Monitoring
Metrics
Logs
Tracing
Request ID
Latency
Throughput
Error Rate
Dashboard
Alert
SLA
SLO
SLI
再把它們放進真正的 Production System。