Saga pattern là một mẫu thiết kế quan trọng trong kiến trúc microservices, được sử dụng để quản lý các giao dịch phân tán (distributed transactions). Hãy cùng tìm hiểu từng bước để bạn có thể nắm vững khái niệm này.
Vấn đề cần giải quyết
Trước tiên, hãy tưởng tượng bạn đang xây dựng một hệ thống thương mại điện tử với kiến trúc microservices. Khi khách hàng đặt hàng, bạn cần thực hiện nhiều thao tác trên các service khác nhau:
- Trừ tiền từ tài khoản khách hàng (Payment Service)
- Giảm số lượng sản phẩm trong kho (Inventory Service)
- Tạo đơn hàng mới (Order Service)
- Gửi email xác nhận (Notification Service)
Trong hệ thống monolithic truyền thống, bạn có thể sử dụng database transaction để đảm bảo tất cả các thao tác này đều thành công hoặc đều thất bại. Nhưng trong microservices, mỗi service có database riêng, và bạn không thể sử dụng ACID transaction xuyên suốt nhiều database.
Saga Pattern là gì?
Saga pattern chia một giao dịch lớn thành một chuỗi các giao dịch nhỏ hơn, mỗi giao dịch được thực hiện bởi một service riêng biệt. Quan trọng nhất, saga định nghĩa cách "hoàn tác" (compensate) mỗi bước nếu có lỗi xảy ra.
Có hai cách triển khai saga pattern chính:
1. Choreography-based Saga
Trong cách này, mỗi service tự quản lý việc gọi service tiếp theo thông qua events. Không có coordinator trung tâm.
Ví dụ flow đặt hàng:
- Order Service tạo đơn hàng và publish event "OrderCreated"
- Payment Service nghe event, trừ tiền và publish "PaymentProcessed"
- Inventory Service nghe event, giảm kho và publish "InventoryReserved"
- Notification Service nghe event và gửi email
Nếu Payment Service thất bại, nó sẽ publish "PaymentFailed", Order Service nghe và tự động hủy đơn hàng.
2. Orchestration-based Saga
Ở đây có một Saga Orchestrator trung tâm điều phối toàn bộ flow.
Orchestrator sẽ:
- Gọi Order Service tạo đơn hàng
- Gọi Payment Service trừ tiền
- Gọi Inventory Service giảm kho
- Gọi Notification Service gửi email
Nếu bước nào thất bại, Orchestrator sẽ gọi các compensation actions theo thứ tự ngược lại.
Tại sao cần Saga Pattern?
1. Đảm bảo Data Consistency
Saga giúp duy trì tính nhất quán dữ liệu trong hệ thống phân tán mà không cần distributed transactions phức tạp và chậm.
2. Fault Tolerance
Khi một bước trong saga thất bại, hệ thống có thể tự động rollback các thay đổi đã thực hiện, đảm bảo hệ thống luôn ở trạng thái nhất quán.
3. Scalability
So với 2-Phase Commit protocol, saga nhẹ hơn và không khóa resources trong thời gian dài, giúp hệ thống có khả năng mở rộng tốt hơn.
4. Resilience
Hệ thống có thể tiếp tục hoạt động ngay cả khi một số services tạm thời không khả dụng, vì saga có thể retry hoặc rollback một cách graceful.
Thách thức cần lưu ý
Saga pattern cũng mang lại một số thách thức mà bạn cần cân nhắc:
Complexity: Bạn cần thiết kế các compensation actions cẩn thận và handle các edge cases như partial failures.
Eventual Consistency: Hệ thống chỉ đạt được eventual consistency chứ không phải immediate consistency như ACID transactions.
Debugging: Việc trace và debug một saga phức tạp có thể khó khăn hơn so với một transaction đơn giản.