Giao diện
📊 DATA CONSISTENCY MODELS
Sự Thật là Tương đối: Khi Dữ liệu "Đúng" Tùy thuộc vào Góc nhìn
Mục tiêu Học tập
Sau khi hoàn thành module này, bạn sẽ có khả năng:
- Phân biệt Strong Consistency và Eventual Consistency
- Hiểu trade-off giữa ACID và BASE
- Chọn consistency model phù hợp cho từng use case
- Áp dụng HPN Case Study vào thực tế
1. The Spectrum of Consistency
NOTE
🎓 Giáo sư Tom: Consistency không phải binary (có hoặc không). Nó là một spectrum - từ "Mọi đọc đều thấy write mới nhất" đến "Cuối cùng thì sẽ đồng bộ". Hiểu spectrum này là chìa khóa để thiết kế hệ thống hiệu quả.
┌─────────────────────────────────────────────────────────────────────────┐
│ CONSISTENCY SPECTRUM │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ STRONG WEAK │
│ (Strict) (Relaxed) │
│ │ │ │
│ ▼ ▼ │
│ ┌──────────┐ ┌────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Linear- │ │ Sequential │ │ Causal │ │ Eventual │ │
│ │ izable │ │Consistency │ │ Consistency │ │ Consistency │ │
│ └──────────┘ └────────────┘ └──────────────┘ └──────────────┘ │
│ │ │ │ │ │
│ │ │ │ │ │
│ "Như một "Mọi client "Respects "Cuối cùng │
│ máy duy thấy cùng cause-effect sẽ đồng bộ" │
│ nhất" thứ tự" relationships" │
│ │
│ ◄───────────────────────────────────────────────────────────────────► │
│ HIGH LATENCY LOW LATENCY │
│ (Coordination required) (No coordination) │
│ │
│ HIGH AVAILABILITY COST HIGH AVAILABILITY │
│ (Partition = unavailable) (Partition = stale ok) │
│ │
└─────────────────────────────────────────────────────────────────────────┘2. Strong Consistency (Linearizability)
2.1 Định nghĩa
Linearizability: Mỗi operation dường như xảy ra tại MỘT thời điểm duy nhất, nằm giữa invocation và response. Mọi client đều thấy cùng một thứ tự các operations.
┌─────────────────────────────────────────────────────────────────────────┐
│ LINEARIZABILITY EXAMPLE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Time → │
│ ═══════════════════════════════════════════════════════════════════ │
│ │
│ Client A: [────── WRITE x=1 ──────] │
│ │ │
│ Linearization │
│ Point │
│ ▼ │
│ Client B: ● [── READ x ──] │
│ │ │
│ ▼ │
│ Must return 1 │
│ │
│ If READ overlaps with WRITE: │
│ - Return old value (0) if read linearizes BEFORE write │
│ - Return new value (1) if read linearizes AFTER write │
│ - But ONCE you return 1, all subsequent reads MUST return 1 │
│ │
└─────────────────────────────────────────────────────────────────────────┘2.2 Implementation Cost
┌─────────────────────────────────────────────────────────────────────────┐
│ STRONG CONSISTENCY COORDINATION │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Write Request: SET balance = 1000 │
│ │
│ Client │
│ │ │
│ ▼ │
│ ┌─────────┐ │
│ │ PRIMARY │ │
│ └────┬────┘ │
│ │ │
│ ├──────────────────┬──────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │REPLICA 1│ │REPLICA 2│ │REPLICA 3│ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ │◄─────── ACK ─────┤ │ │
│ │ │◄─────── ACK ─────┤ │
│ │ │
│ ▼ │
│ ╔═══════════════════════════════════════════╗ │
│ ║ WAIT for ALL replicas to ACK before ║ │
│ ║ responding to client ║ │
│ ║ ║ │
│ ║ Latency = MAX(replica_latencies) + RTT ║ │
│ ╚═══════════════════════════════════════════╝ │
│ │
│ If ANY replica is slow or partitioned: │
│ → Client WAITS or gets TIMEOUT/ERROR │
│ │
└─────────────────────────────────────────────────────────────────────────┘2.3 Use Cases cho Strong Consistency
| Use Case | Tại sao cần Strong? |
|---|---|
| Banking/Payments | Không thể chấp nhận "đôi khi thấy balance sai" |
| Inventory | Tránh oversell (bán nhiều hơn có) |
| Booking Systems | Tránh double-booking |
| Leader Election | Chỉ có thể có 1 Leader |
CAUTION
Chi phí của Strong Consistency:
- Latency: Phải đợi coordination giữa nodes
- Availability: Network partition = unavailable (CAP theorem)
- Throughput: Bottleneck tại coordination layer
3. Eventual Consistency
3.1 Định nghĩa
Eventual Consistency: Nếu không có writes mới, TẤT CẢ replicas sẽ cuối cùng hội tụ về cùng một giá trị.
┌─────────────────────────────────────────────────────────────────────────┐
│ EVENTUAL CONSISTENCY EXAMPLE │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ Video: "Gangnam Style" được like │
│ │
│ Time 0: User in VN likes video │
│ ┌──────────────────────────────────────────────────┐ │
│ │ ASYNC REPLICATION │ │
│ ▼ ▼ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ VN DC │───────────►│ US DC │───────────►│ EU DC │ │
│ │ 1B likes│ │999M │ │999M │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ Time 1: User in US queries │
│ → Sees 999M likes (STALE!) │
│ │
│ Time 2: Replication catches up │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ VN DC │ │ US DC │ │ EU DC │ │
│ │ 1B likes│ │ 1B likes│ │ 1B likes│ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ ✅ EVENTUALLY consistent │
│ ❓ Inconsistent window: Time 1 (có thể vài giây đến vài phút) │
│ │
└─────────────────────────────────────────────────────────────────────────┘3.2 Real-world Examples
TIP
🔧 Kỹ sư Raizo: Nhìn số likes trên Facebook/TikTok. Bạn có để ý rằng refresh page đôi khi thấy số khác nhau không? Đó là Eventual Consistency. 1 tỷ người dùng không cần thấy chính xác cùng một con số - họ chỉ cần thấy "khoảng" đúng.
| Platform | What's Eventually Consistent? |
|---|---|
| Like counts, comment counts | |
| Twitter/X | Follower counts, retweet counts |
| YouTube | View counts, subscriber counts |
| Like counts, story views | |
| TikTok | Hearts, share counts |
3.3 Conflict Resolution Strategies
Khi 2 replicas nhận writes cùng lúc (concurrent writes):
┌─────────────────────────────────────────────────────────────────────────┐
│ CONFLICT RESOLUTION │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. LAST-WRITE-WINS (LWW) │
│ ───────────────────────── │
│ Use timestamp to pick winner │
│ │
│ Replica A: SET name = "Alice" @ T=100 │
│ Replica B: SET name = "Bob" @ T=105 │
│ → Final value: "Bob" (higher timestamp) │
│ │
│ ⚠️ Problem: Clock skew can cause "older" write to win │
│ │
│ 2. VERSION VECTORS / VECTOR CLOCKS │
│ ──────────────────────────────────── │
│ Track causality, detect conflicts │
│ │
│ Replica A: {A:1, B:0} SET name = "Alice" │
│ Replica B: {A:0, B:1} SET name = "Bob" │
│ │
│ Neither dominates → CONFLICT DETECTED │
│ → Merge or ask application to resolve │
│ │
│ 3. CRDTs (Conflict-free Replicated Data Types) │
│ ─────────────────────────────────────────────── │
│ Data structures that auto-merge without conflicts │
│ │
│ G-Counter: Count only goes UP, merge = take MAX per replica │
│ OR-Set: Add-wins semantics for sets │
│ │
└─────────────────────────────────────────────────────────────────────────┘4. ACID vs BASE
4.1 ACID (Traditional RDBMS)
┌─────────────────────────────────────────────────────────────────────────┐
│ ACID PROPERTIES │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ A - ATOMICITY │
│ ═════════════ │
│ All or Nothing │
│ │
│ BEGIN TRANSACTION │
│ ├── Debit Account A: -$100 │
│ ├── Credit Account B: +$100 │
│ └── If ANY fails → ROLLBACK ALL │
│ COMMIT │
│ │
│ C - CONSISTENCY │
│ ═══════════════ │
│ From valid state to valid state │
│ │
│ Invariant: Total money = constant │
│ Before: A=500, B=500 → Total = 1000 │
│ After: A=400, B=600 → Total = 1000 ✓ │
│ │
│ I - ISOLATION │
│ ═════════════ │
│ Concurrent transactions don't interfere │
│ │
│ T1: Read A → Write A │
│ T2: Read A → Write A │
│ Serializability: Result = as if T1 then T2 OR T2 then T1 │
│ │
│ D - DURABILITY │
│ ════════════ │
│ Committed = Permanent (survives crash) │
│ │
│ COMMIT → Write to disk → Return success │
│ Even if machine crashes 1ms later, data is SAFE │
│ │
└─────────────────────────────────────────────────────────────────────────┘4.2 BASE (Modern Distributed Systems)
┌─────────────────────────────────────────────────────────────────────────┐
│ BASE PROPERTIES │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ BA - BASICALLY AVAILABLE │
│ ════════════════════════ │
│ System guarantees availability (CAP's A) │
│ May return stale data, but NEVER errors │
│ │
│ User: "Show me my friend list" │
│ System: Returns cached list (may be 30s old) │
│ → Better than "Service Unavailable" │
│ │
│ S - SOFT STATE │
│ ══════════════ │
│ State may change without explicit input │
│ │
│ Cache entries expire │
│ Session data times out │
│ Replication propagates in background │
│ │
│ E - EVENTUAL CONSISTENCY │
│ ════════════════════════ │
│ Given enough time, all replicas converge │
│ │
│ → No immediate guarantees │
│ → But WILL be consistent eventually │
│ │
└─────────────────────────────────────────────────────────────────────────┘4.3 Comparison Matrix
| Aspect | ACID | BASE |
|---|---|---|
| Focus | Correctness | Availability |
| Consistency | Strong (immediate) | Eventual |
| Isolation | Pessimistic locking | Optimistic, no locks |
| Availability | May sacrifice for consistency | Prioritized |
| Scalability | Vertical (scale up) | Horizontal (scale out) |
| Use Case | Financial, inventory | Social, analytics |
| Examples | PostgreSQL, MySQL | Cassandra, DynamoDB, MongoDB |
5. HPN Case Study: Choosing the Right Model
IMPORTANT
🔧 Kỹ sư Raizo - HPN Architecture Decision:
HPN Premium Store có 2 hệ thống rất khác nhau về yêu cầu consistency:
5.1 Payment System (ACID Required)
┌─────────────────────────────────────────────────────────────────────────┐
│ HPN PAYMENT SYSTEM - STRONG CONSISTENCY │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ User buys course: "Kubernetes Masterclass" - 500,000 VND │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ SINGLE TRANSACTION │ │
│ │ │ │
│ │ 1. BEGIN TRANSACTION │ │
│ │ 2. Check user.balance >= 500,000 ✓ │ │
│ │ 3. UPDATE users SET balance = balance - 500000 │ │
│ │ 4. INSERT INTO purchases (user_id, course_id, amount) │ │
│ │ 5. INSERT INTO enrollments (user_id, course_id) │ │
│ │ 6. COMMIT │ │
│ │ │ │
│ │ If ANY step fails → ROLLBACK (user không mất tiền, không │ │
│ │ được course, atomic!) │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ Database: PostgreSQL (ACID compliant) │
│ Replication: SYNCHRONOUS (wait for replica before commit) │
│ Latency: ~50-100ms per transaction (acceptable for payment) │
│ │
│ ⚠️ If we used eventual consistency: │
│ → User could buy course, money deducted, but enrollment fails │
│ → Inconsistent state, angry customer, refund nightmare │
│ │
└─────────────────────────────────────────────────────────────────────────┘5.2 View Counter System (BASE Acceptable)
┌─────────────────────────────────────────────────────────────────────────┐
│ HPN VIEW COUNTER - EVENTUAL CONSISTENCY │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ User views article: "System Design Interview Tips" │
│ │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ ASYNC UPDATE FLOW │ │
│ │ │ │
│ │ 1. User views → Increment local counter (in-memory) │ │
│ │ 2. Batch writes every 5 seconds to Redis │ │
│ │ 3. Redis async replicates to replica shards │ │
│ │ 4. Periodic flush to persistent storage (every 1 min) │ │
│ │ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │
│ User A sees: 10,523 views │
│ User B sees: 10,518 views (5 seconds earlier snapshot) │
│ │
│ ✅ WHO CARES? Does it matter if views differ by 5? │
│ │
│ Benefits of this approach: │
│ • Latency: <1ms (no disk I/O on read) │
│ • Throughput: 100K+ increments/second │
│ • Availability: Never fails, always returns something │
│ • Cost: 10x cheaper than strong consistency │
│ │
│ Trade-off accepted: │
│ • Views may be slightly stale (acceptable for analytics) │
│ • May lose a few counts on crash (acceptable) │
│ │
└─────────────────────────────────────────────────────────────────────────┘5.3 Decision Framework
6. CAP Theorem Revisited
NOTE
🎓 Giáo sư Tom: CAP Theorem thường bị hiểu sai. Nó KHÔNG nói "chọn 2 trong 3". Nó nói: Khi có network partition, bạn phải chọn giữa Consistency và Availability.
┌─────────────────────────────────────────────────────────────────────────┐
│ CAP THEOREM │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌────────────────┐ │
│ │ CONSISTENCY │ │
│ │ (All nodes see │ │
│ │ same data) │ │
│ └───────┬────────┘ │
│ │ │
│ ┌─────────────┴─────────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ AVAILABILITY │ │ PARTITION │ │
│ │ (Every request │◄────────►│ TOLERANCE │ │
│ │ gets response)│ │ (System works │ │
│ └────────────────┘ │ despite splits)│ │
│ └────────────────┘ │
│ │
│ WHEN PARTITION OCCURS (and it WILL): │
│ ───────────────────────────────────── │
│ │
│ CP: Refuse to respond (protect consistency) │
│ → "Sorry, cannot guarantee data is correct, so I won't answer" │
│ → Examples: ZooKeeper, etcd, traditional RDBMS │
│ │
│ AP: Respond with potentially stale data (protect availability) │
│ → "Here's what I know, might be outdated but you get a response" │
│ → Examples: Cassandra, DynamoDB, CouchDB │
│ │
│ CA: Impossible in distributed system (partitions WILL happen) │
│ │
└─────────────────────────────────────────────────────────────────────────┘7. Scenario Quiz
Câu hỏi 1: E-commerce Inventory
HPN Store bán merchandise. Có 100 cái t-shirt "Rust Ferris" trong inventory. 120 người cùng lúc bấm "Buy" trong flash sale.
Bạn nên dùng Strong hay Eventual Consistency? Tại sao?
👁️ Xem đáp án
Đáp án: STRONG Consistency (ACID)
Lý do:
- Inventory là finite resource - không thể bán 120 cái khi chỉ có 100
- Overselling = ship không đủ hàng = refund + angry customers + bad reputation
- Financial transaction (payment) liên quan
Implementation:
sql
BEGIN TRANSACTION;
SELECT quantity FROM products WHERE id = 'rust-ferris' FOR UPDATE;
-- Check quantity >= 1
UPDATE products SET quantity = quantity - 1 WHERE id = 'rust-ferris';
INSERT INTO orders (product_id, user_id, status) VALUES (...);
COMMIT;Trade-off chấp nhận:
- Một số users sẽ thấy "Out of Stock" (better than oversell)
- Latency cao hơn (acceptable cho purchase flow)
Câu hỏi 2: Social Media Likes
HPN Blog có bài viết viral với 10 triệu views. Mỗi giây có 1000 người like.
Bạn nên dùng Strong hay Eventual Consistency? Tại sao?
👁️ Xem đáp án
Đáp án: EVENTUAL Consistency (BASE)
Lý do:
- Like count KHÔNG CẦN chính xác tuyệt đối
- User A thấy "10,000,523 likes", User B thấy "10,000,519" → Không ai quan tâm
- 1000 likes/second = yêu cầu extreme throughput
- Strong consistency sẽ tạo bottleneck không thể scale
Implementation:
1. Increment in-memory counter (per server)
2. Batch flush to Redis every 5 seconds
3. Async replicate across regions
4. Periodic persist to database (every minute)Trade-off chấp nhận:
- Counts có thể sai vài chục/trăm trong vài giây (acceptable)
- Nếu server crash, mất một vài counts gần nhất (acceptable)
8. Tiếp theo
Bây giờ bạn đã hiểu về Consistency Models, hãy khám phá:
Chúng ta sẽ so sánh REST vs gRPC vs GraphQL - và tại sao internal microservices nên dùng gRPC thay vì REST.