etcd Architecture Deep Dive — Quorum, Replication, Watch Mechanism, Compaction
Tại Sao Cần Hiểu etcd Internals
Đa số Kubernetes engineers chỉ biết etcd là "key-value store mà Kubernetes dùng". Tuy nhiên, hiểu cách etcd vận hành giúp:
- Gỡ lỗi state inconsistencies — Khi dữ liệu ở etcd sai với deployed state
- Dự đoán failure modes — Biết etcd quorum cần bao nhiêu nodes, tránh single-point-of-failure
- Tune performance — Watch connection limits, compaction schedule ảnh hưởng latency
- Capacity planning — Biết object size limits, write throughput ceiling
Raft Consensus Algorithm — Foundation
etcd dựa trên Raft, distributed consensus algorithm. Hiểu Raft rất quan trọng để hiểu etcd.
Core Concept: State Machine Replication
Mong Đợi: Tất cả nodes trong etcd cluster duy trì TRẠNG THÁI GIỐNG HỆT
Cơ Chế: Sao chép mỗi ghi → tất cả nodes áp dụng cùng thứ tự
Client ghi giá trị X
↓
Ghi cho leader
↓
Leader broadcasts "append entry X" cho followers
↓
Followers nhận, persist vào disk, ack
↓
Leader chờ majority ack (quorum)
↓
Leader commits X tới state machine
↓
Leader thông báo followers: "commit X"
↓
Tất cả followers áp dụng X tới state machine
↓
Nhất quán đạt được ✓Quorum Requirement
etcd luôn cần đa số (>50%) nodes hoạt động:
Kích thước Cluster Quorum tối thiểu Dung sai
─────────────────────────────────────
1 1 0 nodes fail
3 2 1 node fail
5 3 2 nodes fail
7 4 3 nodes failẢnh hưởng:
- 1-node cluster: bất kỳ fail = downtime (tránh!)
- 3-node cluster: HA điển hình, dung sai 1 fail
- 5-node cluster: dung sai 2 fail (đắt tiền, hiếm cần)
Tại sao số lẻ?: Quorum cho 4-node = 3, giống 5-node. Tốt hơn dùng 3 hoặc 5.
Leader Election
Bất kỳ lúc nào, etcd cluster có đúng 1 leader:
┌────────────────────────────────────┐
│ Leader │
│ - Nhận client writes │
│ - Broadcasts cho followers │
│ - Commits khi majority acks │
└────────────────────────────────────┘
Followers:
- Sao chép leader state
- Forward client writes cho leader
- Kích hoạt bầu chọn mới nếu leader chết
Leader được bầu chọn: ~150-300ms (tunable)GKE context: etcd leader được bầu chọn tự động bởi GCP, không cần can thiệp thủ công.
Replication Mechanics
Log Replication
etcd maintains replicated log — ordered list of write operations:
Leader Log:
┌──────────────────────────────────────┐
│ [1] PUT /pods/pod1 → data1 │
│ [2] PUT /services/svc1 → data2 │
│ [3] DELETE /configmaps/cfg1 → - │
│ [4] PUT /pods/pod2 → data3 │
│ (uncommitted ↓) │
│ [5] PUT /services/svc2 → data4 │
│ [6] (pending replication) │
└──────────────────────────────────────┘
Followers replicate same log, apply same orderSnapshots Cho Efficiency
etcd không giữ infinite log. Định kỳ:
Log entries 1-1000 → Snapshot
├─ Tất cả entries áp dụng state machine
├─ Take snapshot trạng thái cuối
└─ Discard old log entries
Kết quả:
- Log giữ kích thước quản lý được
- New followers catchup nhanh qua snapshot
- Faster recovery từ crashesGKE etcd compaction: ~mỗi 6 giờ (tunable)
Consistency During Replication
Đảm bảo quan trọng: Followers áp dụng entries trong thứ tự giống hệt như leader:
# Leader có
[ PUT key1=A ]
[ PUT key1=B ]
# Followers sẽ LUÔN thấy theo thứ tự này
# Không bao giờ key1=B rồi key1=A
# Đảm bảo thứ tự này là điều cần thiết cho nhất quánWatch Mechanism — Event Streaming
Cách Watch Hoạt Động (High Level)
Watch là subscriber pattern — clients đăng ký để nhận events:
Client:
kubectl get pods --watch
↓
Mở HTTP connection
↓
Gửi: WATCH /pods
↓
API Server:
Forwards tới etcd
↓
Mở watch subscription
↓
etcd:
Streams ADDED/MODIFIED/DELETED events
├─ Object X thêm → ADDED event
├─ Object X cập nhật → MODIFIED event
└─ Object X xóa → DELETED event
Events chảy lại cho client in real-timeWatch Caching Trong API Server
Không phải mỗi watch trực tiếp từ etcd. API Server duy trì watch cache:
Nhiều Clients watching /pods
├─ Watch 1 (client A)
├─ Watch 2 (client B)
└─ Watch 3 (client C)
↓
API Server Watch Cache
(shared subscription tới etcd)
↓
Single etcd watch
(multiplexed upstream)Efficiency:
- Một etcd watch cho 100 API clients
- Significant reduction etcd watch connections
Latency:
- etcd → API Server cache: <10ms điển hình
- API Server → client: <100ms
Watch Nhất Quán & Thứ Tự
Rất quan trọng: watch events được deliver theo thứ tự:
Nếu Pod spec cập nhật: field1=A → field1=B
Client sẽ thấy:
1. MODIFIED event (field1=A)
2. MODIFIED event (field1=B)
KHÔNG bao giờ out-of-order hoặc bỏ quaWatch Connection Kết Nối Lại
Khi watch connection bị rơi (network interrupt, server restart):
Client:
Connection bị rơi
↓
Thử kết nối lại
↓
Gửi WATCH /pods tại resourceVersion=N
↓
API Server:
"Gửi cho tôi events từ version N"
↓
Streams buffered events
↓
Tiếp tục live streamBuffering: API Server buffer ~1000s events nếu client tạm disconnect
Compaction — Maintaining Database Size
Vấn Đề: Unbounded Growth
Không có compaction, etcd database liên tục grow:
Time 0: PUT key1=A (version 1)
Time 1: PUT key1=B (version 2)
Time 2: PUT key1=C (version 3)
Time 3: PUT key1=D (version 4)
...
Time 1000000: PUT key1=LATEST (version 1000000)
Database lưu tất cả versions!
Disk usage: không giới hạn
Recovery speed: chậm (replay tất cả versions)Compaction Operation
Compaction removes old revisions:
# Triggering compaction (GKE does automatically)
etcdctl compact 100000
# Keep revisions > 100000, discard older
# Result:
# Database size reduced
# Can't read old versions anymore
# Faster recoveryGKE automatic compaction: ~mỗi 6 giờ, giữ lại 1 giờ lịch sử cuối
Side Effects of Compaction
⚠️ Quan Trọng: Sau compaction, old revisions không còn truy cập được:
# Điều này sẽ fail post-compaction
etcdctl get key1 --rev=50000
# LỖI: revision 50000 không có sẵn
# Điều này hoạt động
etcdctl get key1 --rev=150000 # > compaction revisionWatch ảnh hưởng:
- Nếu client watches từ revision 50000 sau-compaction
- etcdctl không thể fulfill (revision xóa)
- etcdctl returns: "watch revision quá cũ"
- Client phải kết nối lại với revision hiện tại
Key & Value Size Constraints
Per-Key Limits
| Limit | Value | Impact |
|---|---|---|
| Max key size | ~512 KB | etcd key paths not typically hit limit |
| Max value size | ~1 MB | ConfigMaps/Secrets > 1MB = reject |
| Total db size | Configurable | Default: unlimited, limited by disk |
Ảnh Hưởng Cho Kubernetes
# ❌ Sẽ từ chối - ConfigMap quá lớn
apiVersion: v1
kind: ConfigMap
metadata:
name: huge-config
data:
large-file: |
[... 10 MB dữ liệu ...] # TỪ CHỐI
# Giải pháp: Lưu trong object storage, chỉ tham chiếu
apiVersion: v1
kind: ConfigMap
metadata:
name: config-ref
data:
storage-url: gs://bucket/fileKích Thước Database etcd
# Kiểm tra kích thước database etcd (GKE)
kubectl exec -n kube-system etcd-server -- \
du -sh /var/lib/etcd
# Giá trị điển hình:
# Small cluster: 100 MB - 1 GB
# Medium cluster: 1 GB - 10 GB
# Large cluster: 10 GB - 100 GBPerformance Characteristics
Write Latency
Typical latency per write:
├─ Network latency to leader: 5 ms
├─ Disk fsync (persistent): 10 ms
├─ Leader commits: 5 ms
├─ Response back to client: 5 ms
└─ Total: ~25 ms (p50), ~100 ms (p99)Write Throughput
etcd bottleneck typically disk I/O:
Single leader can handle:
- Typical writes: ~1000 writes/sec
- Peak writes: ~5000 writes/sec (unsustainable)
Throughput limits:
- Storage IOPS capacity
- Network bandwidth
- Quorum replication latencyWatch Latency
Event latency:
- etcd detects change: immediate
- Broadcasts to followers: <5ms
- API Server buffers: <10ms
- Client receives: <100ms totalFailure Modes & Recovery
Node Failure Impact
3-node cluster:
├─ Node 1 fails: Cluster operational (2/3 quorum)
├─ Node 2 fails: Cluster operational (2/3 quorum)
└─ Nodes 1,2 fail: Cluster DOWN (need 2/3)
Data loss: Zero (quorum always preserved)Leader Failure
Leader crash:
Time 0: Leader crashes
↓
Time 100-200ms: Followers detect (heartbeat missing)
↓
Time 300ms: New leader elected
↓
Time 400ms: Cluster operational againClient impact: Pending writes get re-executed, consistency maintained
Network Partition
Network partition:
├─ Partition 1: 2 nodes (includes leader)
├─ Partition 2: 1 node
Partition 1: Quorum intact → OPERATIONAL
Partition 2: No quorum → READ-ONLY (or rejected)
When healed: Partition 2 catches up automaticallyProduction Best Practices
Cluster Size
Recommendation:
- 3-node: Default production (tolerate 1 failure)
- 5-node: Use if frequent updates (faster catchup dari snapshots)
- 1-node: Development only
Monitoring
# Critical metrics
etcd_server_has_leader # Should always be 1
etcd_server_leader_changes_seen_total # Should increase slowly
etcd_disk_backend_commit_duration_seconds # Should be <50ms
etcd_server_proposals_failed_total # Should be 0Backup Strategy
GKE manages backups automatically, tapi validate:
# Verify backups
gcloud container backups describe <backup> \
--format="table(name, state, create_time)"
# Test restore monthlyReference Dokumentasi
- Raft Paper - Extended Version
- etcd Clustering Guide
- etcd Performance Tuning
- GCP etcd Backup Best Practices
Summary
- Raft consensus: etcd basis, guarantees consistency across replicas
- Quorum requirement: Odd-sized clusters, 3-node typical
- Replication log: Maintains ordering of all operations
- Watch mechanism: Efficient event streaming via caching layer
- Compaction: Removes old revisions, improves performance but affects revision history
- Performance: ~1000 writes/sec ceiling, latency ~25ms median
- Failure recovery: Automatic leader election, transparent client failover