Product Management
Đăng nhập
ESC

Nhập từ khóa để tìm kiếm

↑↓ Di chuyển
Enter Mở
ESC Đóng

Bài 54 — Multi-Region Architecture

Đã đọc 0/14 mục · còn khoảng 14 phút
Cách chúng tôi ghi nhận

Một mục được tính là đã đọc khi nó nằm giữa màn hình đủ lâu so với độ dài của nó (bảng và sơ đồ tính một nửa), bạn vẫn đang cuộn hoặc bấm phím, và bạn đã thấy tới cuối mục. Lướt nhanh hoặc để tab mở không được tính. Chúng tôi chỉ lưu thời gian đọc từng mục — không lưu gì khác.

Mở đầu — vì sao bài này quan trọng

Hãy tưởng tượng bạn là kỹ sư vận hành cho một sàn thương mại điện tử đang tăng trưởng nóng ở Việt Nam. Toàn bộ hệ thống của bạn chạy gọn gàng trong một region duy nhất — ví dụ ap-southeast-1 (Singapore). Mọi thứ ổn định suốt hai năm. Rồi một buổi sáng thứ Hai, cả region đó gặp sự cố diện rộng: control plane lỗi, nhiều Availability Zone (AZ) cùng chập chờn. Website của bạn tắt ngóm trong bốn tiếng, đúng vào ngày sale. Doanh thu bốc hơi, khách hàng chửi rủa trên fanpage, và sếp hỏi bạn một câu duy nhất: "Tại sao chúng ta không có phương án dự phòng ở nơi khác?"

Đó chính là lý do bài học này tồn tại. Ở các bài trước, bạn đã học về High Availability & Multi-AZ (Bài 31) — cách sống sót khi một AZ chết trong cùng một region. Nhưng Multi-AZ không cứu bạn khi cả một region sập. Multi-Region Architecture là bước tiến cao hơn: phân tán hệ thống qua nhiều region địa lý cách xa nhau, để không một sự cố vùng nào có thể đánh sập toàn bộ dịch vụ.

Đây không phải kiến trúc dành cho mọi hệ thống. Nó đắt, phức tạp, và kéo theo hàng loạt bài toán khó về đồng bộ dữ liệu. Nhưng với những dịch vụ đòi hỏi tính liên tục cao — ngân hàng, ví điện tử, nền tảng phục vụ hàng triệu người dùng toàn cầu — thì đây là kỹ năng bắt buộc của một kiến trúc sư cloud thực thụ. Học xong bài này, bạn sẽ hiểu khi nào cần multi-region, chọn mẫu kiến trúc nào, và những cái bẫy chết người khi triển khai.

Khái niệm cốt lõi

Ba động lực chính khiến ta cần multi-region

Trước khi vẽ kiến trúc, phải trả lời câu hỏi: tại sao? Có ba động lực kinh điển, và mỗi động lực dẫn tới một mẫu thiết kế khác nhau.

1. Disaster Recovery (DR) — chống sự cố diện rộng. Một region có thể sập hoàn toàn vì thiên tai, lỗi mạng backbone, hoặc lỗi cấu hình phía nhà cung cấp. Multi-AZ không đủ vì các AZ trong cùng region vẫn chia sẻ một số hạ tầng chung (control plane, đường mạng khu vực). Multi-region cho bạn một "bản sao" hệ thống ở region khác, sẵn sàng gánh tải khi region chính chết.

2. Latency — phục vụ người dùng toàn cầu nhanh hơn. Tốc độ ánh sáng là có thật. Một request từ khách hàng ở Frankfurt tới server đặt tại Singapore mất khoảng 160-180ms chỉ riêng độ trễ mạng, chưa tính xử lý. Nếu bạn đặt bản sao dịch vụ tại một region ở châu Âu, người dùng ở đó được phục vụ từ nơi gần hơn, độ trễ tụt xuống còn 20-40ms. Trải nghiệm khác hẳn.

3. Compliance & Data Residency — tuân thủ luật lưu trú dữ liệu. Nhiều quốc gia yêu cầu dữ liệu công dân phải được lưu trong biên giới nước đó. Ở Việt Nam có Nghị định 13/2023 về bảo vệ dữ liệu cá nhân (PDPL) và Luật An ninh mạng với yêu cầu lưu trữ dữ liệu người dùng trong nước. Châu Âu có GDPR. Nếu bạn phục vụ nhiều thị trường, bạn buộc phải đặt dữ liệu ở region tương ứng — đó là multi-region vì lý do pháp lý, không phải vì kỹ thuật.

Ba động lực này thường đan xen, nhưng bạn phải xác định động lực chủ đạo, vì nó quyết định mẫu kiến trúc.

Các mẫu kiến trúc multi-region

Không phải cứ "nhân đôi ra region khác" là xong. Có một phổ các mẫu, đánh đổi giữa chi phí, độ phức tạp và tốc độ phục hồi (đo bằng RTO — thời gian phục hồi, và RPO — lượng dữ liệu chấp nhận mất, đã học ở Bài 32).

Backup & Restore (multi-region). Bạn chỉ sao lưu dữ liệu sang region khác (ví dụ snapshot, object storage cross-region). Khi region chính chết, bạn dựng lại hạ tầng ở region phụ từ backup. Rẻ nhất, nhưng RTO tính bằng giờ. Phù hợp hệ thống không quá quan trọng.

Pilot Light. Region phụ luôn chạy một "ngọn lửa mồi" tối thiểu — thường là database replica được đồng bộ liên tục, còn tầng compute thì tắt hoặc thu nhỏ. Khi có sự cố, bạn "thổi bùng ngọn lửa": scale up compute và chuyển traffic. RTO tính bằng chục phút, chi phí thấp vì compute gần như không chạy.

Warm Standby. Region phụ chạy một phiên bản thu nhỏ nhưng đầy đủ chức năng của hệ thống. Khi cần, bạn chỉ việc scale nó lên kích thước production và chuyển traffic. RTO vài phút, chi phí trung bình-cao.

Active-Active (Multi-Region Active). Cả hai (hoặc nhiều) region cùng phục vụ traffic thật đồng thời. Đây là đỉnh cao: gần như không có downtime khi một region chết, và bạn tận dụng được lợi thế latency. Nhưng đây cũng là mẫu khó nhất, vì bạn phải giải bài toán đồng bộ dữ liệu hai chiều.

Trái tim của vấn đề: đồng bộ dữ liệu

Compute thì dễ nhân bản — chỉ là copy image, chạy container ở region khác. Dữ liệu mới là chỗ khó. Có ba chiến lược:

  • Active-Passive (một nơi ghi, nơi khác đọc): Chỉ region chính được ghi (write), region phụ nhận bản sao read-only qua replication bất đồng bộ. Đơn giản, tránh xung đột. Nhược điểm: khi failover, có thể mất vài giây dữ liệu chưa kịp replicate (RPO > 0), và phải "promote" replica thành primary.
  • Active-Active với dữ liệu phân vùng (partitioned/sharded): Mỗi region "sở hữu" một tập người dùng riêng. Người dùng Việt Nam ghi vào region VN, người dùng châu Âu ghi vào region EU. Không xung đột vì không ai ghi chồng lên ai. Đây là mẫu rất thực dụng và hay được dùng.
  • Active-Active ghi đồng thời khắp nơi: Dùng database phân tán toàn cầu (như DynamoDB Global Tables, Google Cloud Spanner, Cosmos DB) chấp nhận ghi ở mọi region. Mạnh nhưng phải hiểu rõ mô hình nhất quán (consistency): thường là eventual consistency, và phải có cơ chế giải quyết xung đột (thường là "last writer wins" hoặc CRDT).
Một nguyên tắc nền tảng bạn phải khắc cốt ghi tâm: định lý CAP. Khi hai region bị chia cắt mạng (Partition), bạn chỉ được chọn một trong hai — hoặc Consistency (dừng nhận ghi để dữ liệu không sai lệch), hoặc Availability (vẫn nhận ghi ở cả hai bên, chấp nhận dữ liệu tạm thời khác nhau). Không có bữa trưa miễn phí ở đây.

Định tuyến traffic giữa các region

Có hạ tầng hai region rồi, làm sao đưa người dùng tới đúng nơi và tự động chuyển khi có sự cố? Bạn dùng DNS thông minh (Route 53, Cloud DNS, Azure Traffic Manager) với các chính sách:

  • Latency-based routing: đưa user tới region có độ trễ thấp nhất.
  • Geolocation routing: đưa user tới region theo vị trí địa lý (quan trọng cho data residency).
  • Failover routing kèm health check: khi region chính "chết" theo health check, DNS tự trỏ sang region phụ.
Lưu ý bẫy TTL của DNS: nếu bản ghi có TTL 300 giây, client có thể cache địa chỉ region đã chết tới 5 phút. Đặt TTL thấp (30-60s) cho các bản ghi failover.

Tình huống thực tế

Ví dụ 1 — Ví điện tử "PayViet" và cú sốc data residency

Giả định một ví điện tử tên PayViet, phục vụ 8 triệu người dùng, ban đầu đặt toàn bộ hạ tầng ở Singapore vì độ trễ tới Việt Nam chấp nhận được (~30ms) và dịch vụ cloud ở đó phong phú. Mọi thứ chạy tốt cho tới khi bộ phận pháp chế cảnh báo: theo Nghị định 13/2023 và yêu cầu nội địa hóa dữ liệu, dữ liệu cá nhân người dùng Việt Nam phải được lưu trữ trong lãnh thổ Việt Nam.

PayViet buộc phải chuyển sang kiến trúc multi-region với động lực chủ đạo là compliance, không phải kỹ thuật. Họ chọn mẫu active-active phân vùng theo địa lý: dữ liệu định danh và giao dịch của người dùng VN lưu tại region đặt trong nước (họ dùng một nhà cung cấp cloud nội địa như FPT Cloud/Viettel IDC cho tầng dữ liệu nhạy cảm), còn các dịch vụ phụ trợ không chứa dữ liệu cá nhân (như tính toán khuyến mãi, phân tích ẩn danh) vẫn ở Singapore để tận dụng dịch vụ managed.

Bài học rút ra: động lực multi-region không phải lúc nào cũng đến từ kỹ thuật. Đôi khi luật pháp ép bạn phải phân tán. Và khi đó, bạn phải phân loại dữ liệu rất kỹ — cái nào là "dữ liệu cá nhân" bắt buộc nội địa, cái nào có thể để ở đâu cũng được. Đừng bê nguyên cả hệ thống về nước; chỉ nội địa hóa phần bắt buộc để tiết kiệm chi phí và độ phức tạp.

Ví dụ 2 — Grab và bài toán latency cho người dùng Đông Nam Á

Grab hoạt động khắp Đông Nam Á — Việt Nam, Thái Lan, Indonesia, Singapore, Philippines. Một tài xế ở Jakarta cập nhật vị trí GPS mỗi vài giây; nếu request đó phải bay tới một region duy nhất ở Singapore rồi quay về, độ trễ tích lũy sẽ làm bản đồ giật, việc ghép chuyến (matching) chậm đi. Với dịch vụ real-time như gọi xe, latency là sống còn.

Giả định cách tiếp cận: đặt các region gần với thị trường lớn, phân vùng dữ liệu vận hành theo khu vực (chuyến xe ở Indonesia được xử lý ở region gần Indonesia), và dùng latency-based routing để mỗi app kết nối tới điểm gần nhất. Dữ liệu có tính toàn cục thấp — một chuyến xe ở Jakarta không liên quan gì tới tài xế ở Hà Nội — nên phân vùng theo khu vực rất tự nhiên và tránh được xung đột ghi.

Với dữ liệu cần nhìn toàn cục (ví dụ hồ sơ tài khoản người dùng hay đi công tác nhiều nước), họ dùng một lớp database toàn cầu với eventual consistency: cập nhật hồ sơ ở đâu cũng được, đồng bộ dần sang các region khác trong vài trăm mili-giây.

Bài học rút ra: khi động lực là latency, hãy phân vùng dữ liệu theo cách khớp với hành vi người dùng thực. Đa số dữ liệu mang tính "địa phương" và có thể giữ ở region tương ứng. Chỉ một phần nhỏ cần đồng bộ toàn cục — hãy chấp nhận eventual consistency cho phần đó để đổi lấy availability và tốc độ.

Ví dụ 3 — Sàn TMĐT "ShopNhanh" và cú failover thất bại

ShopNhanh (giả định) là sàn thương mại điện tử, đã đầu tư kiến trúc warm standby giữa Singapore (chính) và Tokyo (phụ). Họ tự tin: database replica ở Tokyo đồng bộ liên tục, compute chạy sẵn ở mức 20%. Nhưng khi region Singapore thực sự gặp sự cố trong đợt Flash Sale, quá trình failover... thất bại. Ba lý do:

Thứ nhất, họ chưa bao giờ diễn tập failover thật. Script promote replica ở Tokyo có bug, không chạy được dưới áp lực. Thứ hai, khi 100% traffic dồn về Tokyo, tầng compute 20% không kịp auto-scale lên 100% — do quota vCPU ở region Tokyo bị giới hạn thấp mà không ai để ý. Thứ ba, DNS TTL đặt 3600 giây, nên nhiều khách vẫn bị trỏ về Singapore đã chết suốt gần một tiếng.

Kết quả: RTO thực tế là 90 phút thay vì "5 phút" như thiết kế trên giấy. Thiệt hại doanh thu ước tính hàng tỷ đồng trong đợt sale.

Bài học rút ra: một kiến trúc multi-region chưa được diễn tập failover thì coi như chưa tồn tại. Bạn phải kiểm tra định kỳ: quota ở region phụ có đủ không, script promote có chạy không, DNS TTL có đủ thấp không, và toàn đội có biết quy trình không. "Hy vọng nó hoạt động" không phải là chiến lược DR.

Hướng dẫn từng bước

Đây là quy trình thực dụng để thiết kế một kiến trúc multi-region:

Bước 1 — Xác định động lực chủ đạo. Hỏi rõ: bạn làm multi-region vì DR, latency, hay compliance? Câu trả lời quyết định mọi thứ phía sau. Đừng làm multi-region chỉ vì "nghe hay ho".

Bước 2 — Xác định RTO và RPO mục tiêu. RTO = chấp nhận downtime bao lâu? RPO = chấp nhận mất bao nhiêu dữ liệu? Từ hai con số này chọn mẫu: RTO giờ → Backup/Restore; RTO phút → Warm Standby; RTO ~0 → Active-Active.

Bước 3 — Phân loại và chọn chiến lược dữ liệu. Lập bảng: dữ liệu nào cần đồng bộ toàn cục, dữ liệu nào phân vùng theo region được, dữ liệu nào chỉ read-only ở region phụ. Đây là bước tốn não nhất và quan trọng nhất.

Bước 4 — Thiết kế tầng dữ liệu. Chọn công nghệ: replica bất đồng bộ (active-passive), hay database toàn cầu (DynamoDB Global Tables / Spanner / Cosmos DB) cho active-active. Xác định rõ mô hình consistency bạn chấp nhận.

Bước 5 — Nhân bản tầng compute và cấu hình. Đảm bảo hạ tầng ở region phụ được dựng bằng IaC (Terraform/CloudFormation) — đã học ở Bài 47-48 — để hai region giống hệt nhau, tránh "region drift" (cấu hình lệch nhau).

Bước 6 — Cấu hình định tuyến và health check. Thiết lập DNS routing policy phù hợp (latency/geo/failover), gắn health check, đặt TTL thấp cho bản ghi failover.

Bước 7 — Kiểm tra quota và giới hạn ở region phụ. Đảm bảo region phụ có đủ quota vCPU, IP, giới hạn dịch vụ để gánh 100% tải khi failover.

Bước 8 — Diễn tập failover (game day). Định kỳ mô phỏng sập region chính, đo RTO/RPO thực tế, sửa những gì hỏng. Đây là bước không được bỏ.

Lỗi thường gặp & mẹo

Lỗi 1 — Nhầm Multi-AZ với Multi-Region. Rất nhiều người nghĩ "tôi đã Multi-AZ rồi, an toàn rồi". Không. Multi-AZ chống lỗi một AZ trong region; Multi-Region chống lỗi cả region. Hai lớp bảo vệ khác nhau, giải quyết rủi ro khác nhau.

Lỗi 2 — Bỏ qua chi phí truyền dữ liệu giữa các region. Cross-region data transfer bị tính phí, và không hề rẻ. Replication liên tục một database lớn giữa hai region có thể tốn hàng nghìn đô mỗi tháng. Luôn ước tính khoản này trước khi thiết kế.

Lỗi 3 — Ảo tưởng về đồng bộ tức thời. Replication luôn có độ trễ. Trong active-passive, khi failover bạn gần như chắc chắn mất vài giây dữ liệu cuối. Hãy thiết kế ứng dụng chịu được điều này (ví dụ idempotency để retry an toàn).

Lỗi 4 — Xung đột ghi trong active-active. Nếu cho phép ghi cùng một bản ghi ở hai region, bạn sẽ gặp xung đột. Đừng tự viết logic resolve nếu chưa hiểu rõ — hãy dùng database được thiết kế sẵn cho multi-region, hoặc tốt hơn: phân vùng để không bao giờ ghi chồng.

Lỗi 5 — Quên phần "trạng thái ẩn". Session, cache, hàng đợi message, secrets — những thứ này cũng cần chiến lược multi-region. Nhiều đội chỉ lo database mà quên session store, dẫn tới người dùng bị đăng xuất khi failover.

Mẹo: Bắt đầu đơn giản. Với đa số công ty Việt Nam, một kiến trúc pilot light hoặc warm standby active-passive là điểm cân bằng tốt giữa chi phí và độ an toàn. Active-active toàn cầu chỉ cần thiết khi bạn thực sự phục vụ nhiều châu lục. Đừng over-engineer.

Mẹo: Dùng IaC ngay từ đầu để hai region không bị lệch cấu hình. Region drift là nguyên nhân số một khiến failover thất bại.

Bài tập thực hành

  • Phân tích động lực: Chọn một hệ thống bạn biết (một app, một website). Trả lời: nếu làm multi-region, động lực chủ đạo là gì — DR, latency hay compliance? Vì sao?
  • Chọn mẫu kiến trúc: Cho một hệ thống đặt RTO = 10 phút, RPO = 30 giây, ngân sách vừa phải. Bạn chọn mẫu nào trong bốn mẫu (Backup/Restore, Pilot Light, Warm Standby, Active-Active)? Giải thích.
  • Bảng phân loại dữ liệu: Với một ví điện tử, hãy lập bảng phân loại: (a) dữ liệu nào bắt buộc nội địa hóa, (b) dữ liệu nào phân vùng theo region, (c) dữ liệu nào chỉ read-only ở region phụ.
  • Thiết kế failover: Vẽ sơ đồ đơn giản cho kiến trúc active-passive hai region gồm: DNS routing, health check, database primary/replica, và tầng compute. Ghi rõ TTL bạn chọn cho DNS.
  • Kịch bản game day: Viết ra 5 câu hỏi bạn sẽ kiểm tra trong một buổi diễn tập failover (gợi ý: quota, script promote, TTL, session, alerting).

Tóm tắt

Multi-Region Architecture là bước tiến vượt lên trên Multi-AZ: thay vì chỉ sống sót khi một AZ chết, bạn phân tán hệ thống qua nhiều region để không một sự cố vùng nào có thể đánh sập toàn bộ dịch vụ. Ba động lực chính là DR (chống sự cố diện rộng), latency (phục vụ người dùng toàn cầu nhanh hơn) và compliance/data residency (tuân thủ luật lưu trú dữ liệu như Nghị định 13/2023 ở Việt Nam hay GDPR ở châu Âu). Xác định đúng động lực chủ đạo là bước đầu tiên và quan trọng nhất.

Có một phổ các mẫu kiến trúc — Backup/Restore, Pilot Light, Warm Standby, Active-Active — đánh đổi giữa chi phí, độ phức tạp và RTO/RPO. Trái tim của mọi thiết kế multi-region là đồng bộ dữ liệu: chọn giữa active-passive (một nơi ghi), phân vùng theo region (tránh xung đột), hay database toàn cầu (ghi khắp nơi, chấp nhận eventual consistency). Luôn nhớ định lý CAP: khi mạng bị chia cắt, bạn phải chọn giữa nhất quán và sẵn sàng.

Cuối cùng, và quan trọng nhất: một kiến trúc multi-region chưa được diễn tập failover thì coi như chưa tồn tại. Hãy dùng IaC để tránh region drift, kiểm tra quota ở region phụ, đặt DNS TTL đủ thấp, và diễn tập thường xuyên. Đừng over-engineer — với đa số hệ thống, warm standby active-passive đã là điểm cân bằng tốt.

Học xong bài này rồi? Tạo tài khoản miễn phí để lưu lại — lần sau vào là biết ngay đang dở ở đâu, và học hết khóa thì có chứng chỉ. Lưu tiến độ của tôi