Business Continuity & Disaster Recovery in the Microservices world

Bài tóm tắt Walmart 2019 3. Quy mô lớn Độ khó: Khó

Walmart · 2019 · 3. Quy mô lớn · Độ khó: Khó — bài gốc

Bối cảnh

  • Hệ Integrated Fulfilment (app và backend cho nhân viên cửa hàng soạn đơn pickup/giao hàng) tăng trưởng mạnh và được viết lại. Yêu cầu chính: liên tục kinh doanh; một sự cố ảnh hưởng khách hàng nhiều nước.
  • Kiến trúc: nhiều microservice event-driven, mỗi service sở hữu database riêng; một bộ triển khai đầy đủ gọi là Ring.

Bài toán

  • Ghi đồng bộ sang datacenter xa thì latency phụ thuộc WAN và độ sẵn sàng tổng giảm (thêm DB xa, thêm đường mạng). Nên dùng replication bất đồng bộ (ví dụ Distributed Availability Groups của SQL Server). Messaging không replicate, vì khâu trạng thái broker với trạng thái DB rất khó; dùng DB để phát lại message.
  • Với microservice, mỗi DB replicate độc lập, nên ở bên dự phòng, ảnh chụp chung của nhiều DB tại một thời điểm có thể không nhất quán. Ba kiểu lỗi: tham chiếu gãy (service A trỏ tới thực thể service B chưa có), split brain giữa view tổng hợp và nguồn sự thật ("thấy trên trang tìm kiếm, mở chi tiết thì 404"), tham chiếu treo (con có, cha không).
  • Bài dẫn định lý BAC (Pardon, Pautasso, Zimmermann): khi backup cả một kiến trúc microservice, không thể có cùng lúc availability và consistency. Theo tác giả, mất bớt dữ liệu mà về trạng thái nhất quán gần nhất còn tốt hơn trạng thái không nhất quán.

Thay đổi chính

  • Reconciliation: mỗi service ghi Entity Mutation Log (thay đổi gì, lúc nào). Khi failover, một service "bully" được chỉ định phát lại thay đổi của n phút gần nhất (n chỉnh được, phủ độ trễ replication tối đa) dưới dạng message; service phía dưới tự dựng lại trạng thái. Yêu cầu bắt buộc: mọi consumer idempotent (vốn cần vì broker chỉ at-least-once).
  • Monitor hai tầng: worker trong mỗi Ring gom health check chuẩn hoá (app, DB, broker), master có góc nhìn toàn cầu và ra lệnh failover. Mọi API đi qua GSLB: failover là đổi VIP mà FQDN trỏ tới.
  • Quy trình failover: chặn traffic vào Ring hỏng (trả 503 tạm), failover DB, chạy reconciliation, trỏ GSLB sang Ring dự phòng. Không phải lỗi nào cũng đáng failover vì failover có giá.
  • App chịu được gián đoạn backend: tải trước tài nguyên, lưu cục bộ bền qua restart, đồng bộ nền với ID cho từng giao dịch UI để backend ghép lại đúng thứ tự.
  • Kết quả theo Walmart: quy trình failover mất vài phút nhưng RPO và RTO cảm nhận gần như tức thì vì app vẫn chạy. Tối ưu chi phí: thay active-passive bằng ghép cặp Ring, mỗi Ring vừa chạy thật vừa là dự phòng của cặp mình.

Bài học cho SWE

Liên quan