Multi-region: khi cả một region chết

4 câu hỏi~30 phútTừ khóa: failure domain, RTO, RPO, backup/restore, pilot light, warm standby, active-active, replication lag, write conflict, DNS failover, CAP

Tiếp đi: multi-region và disaster recovery.

Đây là bài cuối của chương. Kiến trúc hiện tại có thể rất tốt: Gateway, services, Redis, DB, Kafka, tất cả chạy nhiều instance trong Region Singapore. Nhưng nếu cả region chết thì sao?

Region Singapore 💀  →  hệ thống 💀
Nhiều instance trong cùng region không cứu được lỗi cấp region.

1. Failure domain

A1, A2, A3 cùng một máy      → máy chết  → cả ba chết
rải ra nhiều máy             → chịu được máy chết
rải ra nhiều AZ (zone)       → chịu được mất một datacenter   (xem bài 14.6)
rải ra nhiều region          → chịu được mất cả vùng

Multi-AZ là mặc định cho production. Multi-region chỉ khi business thật sự yêu cầu, vì đắt và phức tạp hơn rất nhiều.

2. Requirements: RTO và RPO

RTO (Recovery Time Objective)  → TIME : được phép down bao lâu?
    RTO = 30 phút: region chết 10:00 → phục vụ lại trước ~10:30
RPO (Recovery Point Objective) → DATA : chấp nhận mất bao nhiêu dữ liệu?
    RPO = 5 phút: thảm hoạ có thể mất tối đa ~5 phút dữ liệu

Câu đầu tiên trong phỏng vấn: "RTO và RPO mục tiêu là bao nhiêu?". Mọi lựa chọn sau đó đi ra từ hai con số này. Một hệ thống cũng không cần cùng RPO cho mọi loại dữ liệu: ảnh đại diện thì nới, sổ cái tài chính thì rất chặt.

3. Bốn chiến lược DR

Backup/Restore : Region A ──backup──► Object Storage (region khác)
                 thảm hoạ → dựng hạ tầng (Terraform), restore DB, deploy, chạy

Pilot Light    : Region B có DB replica + hạ tầng tối thiểu, compute tắt
                 thảm hoạ → bật/scale compute, promote DB, chuyển traffic

Warm Standby   : Region B chạy đủ stack ở 20% capacity
                 thảm hoạ → scale 20% → 100%, chuyển traffic

Active-Active  :          Global routing
                          /            \
                    Region A 50%    Region B 50%
                 thảm hoạ → toàn bộ traffic sang B
Chiến lượcRTORPOChi phíĐộ phức tạp
Backup/RestoreGiờGiờ (theo chu kỳ backup)ThấpThấp
Pilot LightHàng chục phútGiây–phútThấp–vừaVừa
Warm StandbyPhútGiây–phútVừa–caoVừa
Active-ActiveGần 0Gần 0 (nếu xử lý được conflict)CaoRất cao

Không phải hệ thống nào cũng cần active-active. Hệ thống nội bộ chấp nhận RTO vài giờ thì backup/restore là đủ.

4. Kiến trúc warm standby (lựa chọn phổ biến)

                         Users
                           │
              Global DNS / Traffic routing (health check)
                 /                            \
                ▼ (100%)                       ▼ (0%, sẵn sàng)
   ┌─────────── Region A ──────────┐   ┌────────── Region B ──────────┐
   │ Gateway → Services (N)        │   │ Gateway → Services (N/5)     │
   │ Redis (cache, rebuild được)   │   │ Redis (trống)                │
   │ DB primary ───────────────────┼──►│ DB replica (async)           │
   │ Kafka ────── MirrorMaker ─────┼──►│ Kafka                        │
   │ Object storage ── CRR ────────┼──►│ Object storage               │
   └───────────────────────────────┘   └──────────────────────────────┘
   + secrets/config replicate, IaC giống nhau, runbook failover, diễn tập định kỳ

5. Global routing

DNS hoặc edge (Route 53, Azure Front Door/Traffic Manager, Cloudflare) kiểm tra health của mỗi region. Region A không khoẻ thì trả về địa chỉ region B.

6. Không chỉ DB cần DR

Thành phầnCách DRGhi chú
DBCross-region replica / global databasePhần khó nhất
Redis cacheKhông cần, rebuild từ DBNếu đúng chỉ là cache
KafkaMirrorMaker 2 / cluster linkingOffset khác nhau → consumer phải idempotent, chấp nhận replay
Object storageCross-region replicationRPO theo mức quan trọng
Secrets, config, IaCReplicate, deploy được ở cả hai nơiHay bị quên nhất

Chạy thêm Spring Boot ở region khác thì dễ rồi. Vậy cái khó của multi-region nằm ở đâu?

Đúng, khó nhất là dữ liệu: replication, consistency, conflict, latency.

1. Single-writer (primary ở một region)

Region A: primary (WRITE)  ──async──►  Region B: replica (READ)
A chết → promote B thành primary

Ưu: nhất quán đơn giản, không có conflict. Nhược: thời gian failover, user ở xa ghi chậm (phải đi về region A), và replication lag.

2. Replication lag chính là RPO

Region A: X = 100  ──(chưa kịp replicate)──  Region B: X = 90
A chết → promote B → X = 90   → mất cập nhật cuối = data loss
ReplicationRPOĐổi lại
Async> 0 (bằng lag, thường giây)Ghi nhanh, region B chết không ảnh hưởng A
Sync cross-region≈ 0Mỗi lần ghi chờ thêm một vòng RTT (~50–200ms); B chậm thì A cũng chậm

Không có free lunch. Xem lại Replication.

3. Multi-writer (active-active ghi cả hai nơi)

User 1 sửa X ở Region A: X = "a"
User 2 sửa X ở Region B: X = "b"   (cùng lúc)
→ replicate chéo → X = ? ⚠️ conflict

Các cách giải conflict:

4. CAP trong thực tế

Network partition: Region A ✂ Region B
Cả hai vẫn nhận ghi    → availability ↑, conflict ↑   (AP)
Một bên dừng ghi       → consistency ↑, availability ↓ (CP)

Thực tế chọn theo từng loại dữ liệu: giỏ hàng, like, feed chọn AP; số dư, tồn kho chọn CP. Chi tiết ở Consistency & CAP.

Active-active RTO gần bằng 0, vậy sao không làm active-active cho mọi hệ thống luôn?

Vì nó tăng độ phức tạp rất nhiều, nhất là ở dữ liệu, và chi phí gần như gấp đôi. Câu trả lời tốt trong phỏng vấn:

Em sẽ hỏi RTO/RPO và chi phí chấp nhận được trước. Active-active chỉ đáng khi business thật sự cần downtime gần 0 và dữ liệu chia được theo region hoặc chịu được eventual consistency.

1. Failover phải làm gì (runbook warm standby)

1. Phát hiện: health check region A fail liên tục N phút, người trực xác nhận
2. Chặn ghi ở A (nếu A còn sống một phần) → tránh split-brain
3. Promote DB replica ở B thành primary
4. Scale compute B 20% → 100%
5. Chuyển DNS/traffic sang B
6. Kiểm tra: smoke test, metric lỗi, độ trễ
7. Sau sự cố: đối soát dữ liệu chưa kịp replicate, dựng lại A thành replica

Bước 2 rất quan trọng: nếu A chỉ mất kết nối chứ chưa chết, hai primary cùng nhận ghi gọi là split-brain.

2. DR chưa diễn tập = chưa có DR

Diễn tập failover định kỳ (game day), đo RTO/RPO thực tế. Backup chưa từng restore thử thì không biết có dùng được không (xem Backup & restore).

Phỏng vấn hỏi "hệ thống của bạn chịu được mất cả một region không" thì trả lời sao?

Q1. RTO và RPO là gì?

🇻🇳 Tiếng Việt:

RTO là thời gian tối đa được phép down khi có sự cố. RPO là lượng dữ liệu tối đa được phép mất, tính theo thời gian. Hai con số này do business quyết định và chúng chọn ra chiến lược DR.

🇬🇧 English:

RTO is the maximum acceptable downtime after a disaster. RPO is the maximum acceptable data loss, measured in time. The business sets both numbers, and they drive the choice of DR strategy.

Q2. So sánh các chiến lược DR?

🇻🇳 Tiếng Việt:

Backup/restore rẻ nhất nhưng RTO tính bằng giờ. Pilot light giữ DB replica và hạ tầng tối thiểu ở region khác. Warm standby chạy sẵn bản thu nhỏ, failover trong vài phút. Active-active phục vụ ở cả hai region, RTO gần 0 nhưng đắt và phải xử lý write conflict. Em thường chọn warm standby với single writer, trừ khi requirement đòi hỏi hơn.

🇬🇧 English:

Backup and restore is the cheapest but has an RTO of hours. Pilot light keeps a database replica and minimal infrastructure in another region. Warm standby runs a scaled-down copy and fails over in minutes. Active-active serves traffic from both regions with near-zero RTO, but it is expensive and must handle write conflicts. I usually choose warm standby with a single writer unless the requirements demand more.

Q3. Multi-region khó nhất ở đâu?

🇻🇳 Tiếng Việt:

Ở dữ liệu. Replication async thì lag chính là RPO; replication sync thì mỗi lần ghi chậm thêm một vòng cross-region. Ghi ở nhiều region thì có conflict, nên em ưu tiên chia dữ liệu theo home region, và chỉ cho dữ liệu cần nhất quán mạnh được ghi ở một nơi. Routing failover chỉ quyết định request đi đâu, không giải quyết consistency.

🇬🇧 English:

The data. With asynchronous replication, the lag is your RPO; with synchronous replication, every write pays a cross-region round trip. Writing in multiple regions causes conflicts, so I prefer partitioning data by home region and keeping strongly consistent data single-writer. Routing failover only decides where requests go; it doesn't solve consistency.

Cách nhớ ngắn gọn


Tổng kết chương 14: System Design

BàiĐềConcept chính
15.1Khung trả lời phỏng vấnRequirements → scale → API → data → kiến trúc → deep dive → trade-off
15.2Requirement, SLO, capacityFunctional/non-functional, SLO, ước lượng QPS và storage
15.3Scale app, scale DBStateless, load balancer, cache, read replica, sharding
15.4Rate limitingToken bucket, sliding window, Redis
15.5API GatewayMột cửa vào, auth, routing
15.6High AvailabilityRedundancy, health check, failover, multi-AZ
15.7URL ShortenerSinh ID, cache, read-heavy, sharding
15.8File UploadObject storage, signed URL, CDN
15.9NotificationQueue, retry, DLQ, priority
15.10Ticket BookingRace condition, locking, hold/expire
15.11PaymentIdempotency, UNKNOWN, webhook, reconciliation
15.12Flash saleAtomic claim, Redis Lua, waiting room, oversell
15.13ChatWebSocket, presence, ordering per conversation, dedup
15.14News FeedFan-out write/read, celebrity, hybrid
15.15Banking transferDouble-entry ledger, lock ordering, saga, đối soát
15.16Multi-regionRTO/RPO, DR strategy, replication, CAP

Tự kiểm tra

RTO và RPO khác nhau thế nào?

RTO là thời gian được phép down. RPO là lượng dữ liệu được phép mất (tính theo thời gian).

Pilot light khác warm standby chỗ nào?

Pilot light chỉ có dữ liệu replicate và hạ tầng tối thiểu, compute chưa chạy. Warm standby chạy sẵn cả stack ở capacity nhỏ, nên failover nhanh hơn.

Vì sao replication lag liên quan RPO?

Region primary chết thì phần dữ liệu chưa kịp replicate sẽ mất. Lag càng lớn, RPO thực tế càng lớn.

DNS failover có giải quyết consistency không?

Không. Nó chỉ quyết định request đi tới region nào. Dữ liệu nhất quán phụ thuộc replication và chiến lược ghi.

Split-brain là gì, tránh thế nào?

Hai region cùng nghĩ mình là primary và cùng nhận ghi. Tránh bằng cách chặn ghi ở region cũ (fencing) trước khi promote region mới.