1. Overview
분산 트랜잭션을 보장하는 방법
마이크로서비스 아키텍처는 애플리케이션을 작고 독립적인 서비스로 분리하여 개발, 배포 및 확장을 용이하게 함. 하지만. 이러한 분산 환경에서는 여러 서비스에 걸쳐 데이터를 일관되게 유지하는 ‘분산 트랜잭션’이라는 복잡한 문제가 발생하는데 전통적인 단일 데이터베이스 트랜잭션 방식으로는 이 문제를 해결하기 어려움
Saga 패턴은 이러한 분산 트랜잭션 문제를 해결하기 위한 강력한 아키텍처 패턴이고, 각 서비스가 자체 데이터베이스를 가질 수 있도록 하면서도, 여러 서비스에 걸친 비즈니스 프로세스의 데이터 일관성을 보장하는 방법을 제공함
2. What is the Saga Pattern?
정의
Saga 패턴은 일련의 로컬 트랜잭션(local transactions)으로 구성됨. 여기서 각 로컬 트랜잭션은 단일 서비스 내에서 실행되며, 해당 서비스의 데이터베이스에 대한 ACID(Atomicity, Consistency, Isolation, Durability) 속성을 보장함. Saga는 이 로컬 트랜잭션들이 순차적으로 실행되면서 전체 비즈니스 프로세스를 완료함.
핵심 개념: 보상 트랜잭션 (Compensating Transactions)
Saga 패턴의 핵심은 보상 트랜잭션(compensating transactions) 으로, Saga의 중간 단계에서 어떤 로컬 트랜잭션이 실패하면, 이전에 성공했던 로컬 트랜잭션들의 변경 사항을 되돌리기 위해 보상 트랜잭션이 실행됨. 보상 트랜잭션은 멱등성(idempotent)을 가지며 재시도 가능하도록 설계되어야 함. 이를 통해 Saga는 모든 로컬 트랜잭션이 성공적으로 완료되거나, 실패 시 모든 이전 작업이 적절히 취소되어 데이터 일관성을 유지하도록 보장함
3. Saga Execution Coordinator (SEC)
Saga Execution Coordinator (SEC)는 Saga의 전체 흐름을 관리하는 중앙 구성 요소
- Saga 흐름 관리: Saga의 각 단계가 올바른 순서로 실행되도록 조정
- 이벤트 시퀀스 캡처: Saga 실행 중 발생하는 모든 이벤트를 Saga 로그에 기록하여 추적
- 보상 트랜잭션 오케스트레이션: Saga 중간에 실패가 발생하는 경우, Saga 로그를 참조하여 이전에 성공했던 로컬 트랜잭션에 대한 보상 트랜잭션을 적절한 순서로 호출하여 롤백을 수행함
SEC는 Saga의 상태를 추적하고, 실패 시 복구 메커니즘을 트리거하는 데 중요한 역할을 합니다.
4. Saga Implementation Approaches
Saga 패턴을 구현하는 두 가지 주요 접근 방식이 있습니다: Choreography(안무)와 Orchestration(오케스트레이션).
Choreography-based Saga (안무 기반 Saga)
- 설명: 각 마이크로서비스가 이벤트를 발행하고 구독함으로써 Saga의 다음 단계를 트리거. 중앙 집중식 코디네이터 없이 서비스들이 서로 직접 통신하며 “안무”를 추는 것처럼 동작합니다.
- 장점:
- 서비스 간의 결합도가 낮습니다.
- 새로운 프로젝트(greenfield development)에 적합하며, 참여하는 서비스의 수가 적을 때 효과적입니다.
- 단점:
- 참여하는 서비스가 많아질수록 Saga의 전체 흐름을 추적하고 관리하기가 복잡해질 수 있습니다.
- 디버깅이 어려울 수 있습니다.
Orchestration-based Saga (오케스트레이션 기반 Saga)
- 설명: 단일 오케스트레이터(orchestrator)가 Saga의 전체 트랜잭션 상태를 관리하고, 각 마이크로서비스에 필요한 작업을 직접 호출합니다. 실패 시 오케스트레이터가 보상 트랜잭션을 호출합니다.
- 장점:
- 중앙 집중식 제어로 복잡한 Saga를 관리하기 쉽습니다.
- 기존 마이크로서비스(brownfield development)에 Saga 패턴을 적용할 때 유용합니다.
- 단점:
- 오케스트레이터가 단일 실패 지점(single point of failure)이 될 수 있으므로, 오케스트레이터 자체의 탄력적인 설계가 중요합니다.
- 서비스들이 오케스트레이터에 대한 결합도가 높아질 수 있습니다.
5. Example: E-commerce Order Processing
전자상거래 애플리케이션에서 온라인 주문을 처리하는 Saga 패턴의 예를 살펴보겠습니다. 이 프로세스는 다음과 같은 마이크로서비스를 포함합니다:
- 주문 생성 서비스 (Create Order Service): 고객의 주문을 생성하고 초기 상태로 설정합니다.
- 결제 처리 서비스 (Process Payment Service): 고객의 결제를 처리합니다.
- 재고 업데이트 서비스 (Update Inventory Service): 주문된 상품의 재고를 감소시킵니다.
- 주문 배송 서비스 (Deliver Order Service): 주문된 상품의 배송을 시작합니다.
실패 시나리오: 만약 결제 처리 서비스에서 결제가 실패했다고 가정해 봅시다.
- 보상 트랜잭션 작동: 결제 실패가 감지되면, Saga Execution Coordinator (또는 Choreography의 경우 이전 서비스)는 이전에 성공했던 로컬 트랜잭션에 대한 보상 트랜잭션을 호출합니다.
- 재고 업데이트 서비스는 감소시켰던 재고를 다시 증가시키는 보상 트랜잭션을 실행합니다.
- 주문 생성 서비스는 생성했던 주문을 취소 상태로 변경하는 보상 트랜잭션을 실행합니다.
이러한 방식으로, 결제 실패에도 불구하고 전체 시스템의 데이터 일관성이 유지됩니다.
Two Phase Commit (2PC)
Org Traditional 분산트랜잭션 분산 트랜잭션을 관리하는 전통적인방법으로 2PC가 있지만 아래 한계점을 가짐
- 단일 실패 지점: 2PC는 코디네이터가 단일 실패 지점이 되어, 코디네이터가 다운되면 전체 시스템이 멈출 수 있습니다.
- 느린 성능: 모든 참여자가 커밋에 동의할 때까지 리소스를 잠그기 때문에 성능이 저하될 수 있습니다.
- NoSQL 데이터베이스 지원 부족: 대부분의 NoSQL 데이터베이스는 2PC를 지원하지 않습니다.
반면 Saga 패턴은 이러한 2PC의 단점을 극복합니다. Saga는 각 서비스가 독립적으로 로컬 트랜잭션을 관리하고, 실패 시 보상 트랜잭션을 통해 유연하게 롤백함으로써 분산 시스템의 탄력성과 확장성을 유지합니다. Saga는 엄격한 ACID 속성 대신 “최종 일관성(eventual consistency)”을 목표로 하며, 이는 마이크로서비스 아키텍처에 더 적합함
7. Conclusion
Saga 패턴은 마이크로서비스 아키텍처에서 분산 트랜잭션의 복잡성을 효과적으로 관리하기 위한 필수적인 도구입니다. Choreography와 Orchestration이라는 두 가지 구현 접근 방식을 통해 개발자는 프로젝트의 특성과 요구 사항에 맞춰 유연하게 선택할 수 있습니다.
Saga 패턴을 사용함으로써 우리는 분산 시스템에서 데이터 일관성을 유지하고, 시스템의 탄력성과 확장성을 향상시킬 수 있습니다. 마이크로서비스 환경에서 견고하고 신뢰할 수 있는 애플리케이션을 구축하는 데 Saga 패턴은 중요한 역할을 할 것입니다.