

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Saga 코레오그래피 패턴
<a name="saga-choreography"></a>

## 의도
<a name="saga-choreography-intent"></a>

Saga 코레오그래피 패턴은 이벤트 구독을 사용하여 여러 서비스에 걸친 분산 트랜잭션에서 데이터 무결성을 유지하는 데 도움이 됩니다. 분산 트랜잭션에서는 트랜잭션이 완료되기 전에 여러 서비스를 직접적으로 호출할 수 있습니다. 서비스가 여러 데이터 스토어에 데이터를 저장하는 경우 이러한 데이터 스토어 전반에서 데이터 일관성을 유지하기가 어려울 수 있습니다.

## 목적
<a name="saga-choreography-motivation"></a>

*트랜잭션*은 여러 단계를 포함할 수 있는 단일 작업 단위로, 모든 단계가 완전히 실행되거나 어떤 단계도 실행되지 않기 때문에 데이터 스토어의 일관된 상태가 유지됩니다. *원자성, 일관성, 격리 및 내구성(ACID)*이라는 용어로 트랜잭션의 속성이 정의됩니다. 관계형 데이터베이스는 데이터 일관성을 유지하기 위해 ACID 트랜잭션을 제공합니다.

트랜잭션의 일관성을 유지하기 위해 관계형 데이터베이스는 2단계 커밋(2PC) 방식을 사용합니다. 이는 *준비 단계*와 *커밋 단계*로 구성됩니다.
+ 준비 단계에서는 조정 프로세스를 통해 트랜잭션의 참여 프로세스(참가자)에 트랜잭션을 커밋 또는 롤백할 것을 약속하도록 요청합니다.
+ 커밋 단계에서 조정 프로세스는 참가자에게 트랜잭션을 커밋하도록 요청합니다. 참가자가 준비 단계에서 커밋에 동의하지 않으면 트랜잭션이 롤백됩니다.

서비스별 데이터베이스 설계 패턴을 따르는 분산 시스템에서는 2단계 커밋이 선택 사항이 아닙니다. 이는 각 트랜잭션이 다양한 데이터베이스에 분산되어 있고 관계형 데이터 스토어의 2단계 커밋과 유사한 프로세스를 조정할 수 있는 단일 컨트롤러가 없기 때문입니다. 이 경우 해결 방법 중 하나는 Saga 코레오그래피 패턴을 사용하는 것입니다.

## 적용 가능성
<a name="saga-choreography-applicability"></a>

다음과 같은 경우에 Saga 코레오그래피 패턴을 사용합니다.
+ 시스템에서 여러 데이터 스토어에 걸친 분산 트랜잭션의 데이터 무결성과 일관성이 요구됩니다.
+ 데이터 스토어(예: NoSQL 데이터베이스)는 ACID 트랜잭션을 제공하기 위한 2PC를 제공하지 않으므로, 단일 트랜잭션 내에서 여러 테이블을 업데이트해야 하며 애플리케이션 경계 내에서 2PC를 구현하기가 복잡합니다.
+ 참가자 트랜잭션을 관리하는 중앙 제어 프로세스가 단일 장애 지점이 될 수 있습니다.
+ Saga 참가자는 독립적인 서비스이므로 느슨하게 결합되어야 합니다.
+ 비즈니스 도메인의 제한된 컨텍스트 간에 커뮤니케이션이 이루어집니다.

## 문제 및 고려 사항
<a name="saga-choreography-issues"></a>
+ **복잡성:** 마이크로서비스의 수가 증가하면 마이크로서비스 간의 상호 작용이 많아져 Saga 코레오그래피를 관리하기가 어려워질 수 있습니다. 또한 보정 트랜잭션 및 재시도로 인해 애플리케이션 코드의 복잡성이 가중되어 유지 관리 오버헤드를 초래할 수 있습니다. 코레오그래피는 Saga의 참가자가 소수에 불과하고 단일 장애 지점이 없는 간단한 구현이 필요한 경우에 적합합니다. 참가자가 더 추가되면 이 패턴을 사용하여 참가자 간의 종속성을 추적하기가 더 어려워집니다.
+ **탄력적인 구현:** Saga 코레오그래피에서는 시간 초과, 재시도 및 기타 복원력 패턴을 전반적으로 구현하기가 Saga 오케스트레이션에 비해 더 어렵습니다. 코레오그래피는 오케스트레이터 수준이 아닌 개별 구성 요소에 구현되어야 합니다.
+ **주기적 종속성:** 참가자들은 서로가 게시한 메시지를 소비합니다. 이로 인해 주기적 종속성이 발생하여 코드 복잡성과 유지 관리 오버헤드가 발생하고 교착 상태가 발생할 수 있습니다.
+ **이중 쓰기 문제:** 마이크로서비스는 데이터베이스를 자동으로 업데이트하고 이벤트를 게시해야 합니다. 두 작업 중 하나가 실패하면 상태가 일관되지 않을 수 있습니다. 이 문제를 해결하는 방법 중 하나는 [트랜잭션 아웃박스 패턴](transactional-outbox.md)을 사용하는 것입니다.
+ **이벤트 보존:** Saga 참가자들은 게시된 이벤트에 따라 작동합니다. 감사, 디버깅 및 재생을 위해 이벤트를 발생한 순서대로 저장하는 것이 중요합니다. 데이터 일관성을 복원하기 위해 시스템 상태를 재생해야 하는 경우 [이벤트 소싱 패턴](event-sourcing.md)을 사용하여 이벤트 스토어에 이벤트를 유지할 수 있습니다. 이벤트 스토어는 시스템의 모든 변경 사항을 반영하므로 감사 및 문제 해결 목적으로도 사용할 수 있습니다.
+ **최종 일관성**: 로컬 트랜잭션을 순차적으로 처리하면 최종 일관성이 유지되며, 이는 강력한 일관성이 필요한 시스템에서는 까다로운 과제가 될 수 있습니다. 정합성 모델에 대한 비즈니스 팀의 기대치를 설정하거나 사용 사례를 재평가하여 강력한 일관성을 제공하는 데이터베이스로 전환함으로써 이 문제를 해결할 수 있습니다.
+ **멱등성**: Saga 참가자는 예상치 못한 충돌 및 오케스트레이터 장애로 인한 일시적 장애 발생 시, 반복 실행을 허용할 수 있는 멱등성을 갖추어야 합니다.
+ **트랜잭션 격리**: Saga 패턴은 ACID 트랜잭션의 네 가지 속성 중 하나인 트랜잭션 격리를 지원하지 않습니다. 트랜잭션의 [격리 정도](https://docs.aws.amazon.com/neptune/latest/userguide/transactions-isolation-levels.html)에 따라 다른 동시 트랜잭션이 기반이 되는 데이터에 어느 정도 영향을 미칠 수 있는지 결정됩니다. 트랜잭션을 동시에 오케스트레이션하면 데이터가 부실해질 수 있습니다. 이러한 시나리오를 처리하려면 시맨틱 잠금을 사용하는 것이 좋습니다.
+ **관찰성**: 관찰성이란 구현 및 오케스트레이션 프로세스의 문제를 해결하기 위한 상세한 로깅과 추적을 의미합니다. 이는 Saga 참가자 수가 증가하여 디버깅이 복잡해질 경우에 중요해집니다. Saga 오케스트레이션에 비해 Saga 코레오그래피에서는 엔드 투 엔드 모니터링 및 보고를 실현하기가 더 어렵습니다.
+ **지연 문제**: Saga가 여러 단계로 구성된 경우 보정 트랜잭션으로 인해 전체 응답 시간에서 지연 시간이 늘어날 수 있습니다. 트랜잭션이 동기식으로 직접 호출을 수행하는 경우 지연 시간이 더 늘어날 수 있습니다.

## 구현
<a name="saga-choreography-implementation"></a>

### 전반적인 아키텍처
<a name="saga-choreography-high-level-arch"></a>

다음 아키텍처 다이어그램에서 Saga 코레오그래피에는 주문 서비스, 인벤토리 서비스, 결제 서비스라는 세 가지 참가자가 참여합니다. 트랜잭션을 완료하려면 T1, T2, T3의 세 단계가 필요합니다. 세 가지 보정 트랜잭션은 데이터를 초기 상태(C1, C2, C3)로 복원합니다.

![\[전반적인 Saga 코레오그래피 아키텍처\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/cloud-design-patterns/images/saga-choreography-1.png)

+ 주문 서비스는 데이터베이스를 자동으로 업데이트하고 메시지 브로커에 `Order placed` 메시지를 게시하는 로컬 트랜잭션 T1을 실행합니다.
+ 재고 서비스는 주문 서비스 메시지를 구독하고 주문이 생성되었다는 메시지를 받습니다.
+ 재고 서비스는 데이터베이스를 자동으로 업데이트하고 메시지 브로커에 `Inventory updated` 메시지를 게시하는 로컬 트랜잭션 T2를 실행합니다.
+ 결제 서비스는 재고 서비스의 메시지를 구독하고 재고가 업데이트되었다는 메시지를 수신합니다.
+ 결제 서비스는 데이터베이스에서 결제 세부 정보를 자동으로 업데이트하고 메시지 브로커에 `Payment processed` 메시지를 게시하는 로컬 트랜잭션 T3를 실행합니다.
+ 결제가 실패하면 결제 서비스는 보정 트랜잭션인 C1을 실행합니다. 이 트랜잭션은 데이터베이스의 결제를 원자적으로 되돌리고 메시지 브로커에 `Payment failed` 메시지를 게시합니다.
+ 보정 트랜잭션 C2 및 C3는 데이터 일관성을 복원하기 위해 실행됩니다.

### AWS 서비스를 사용한 구현
<a name="saga-choreography-aws-services"></a>

Amazon EventBridge를 사용하여 Saga 코레오그래피 패턴을 구현할 수 있습니다. EventBridge는 이벤트를 사용하여 애플리케이션 구성 요소를 연결합니다. 그리고 이벤트 버스 또는 파이프를 통해 이벤트를 처리합니다. 이벤트 버스는 [이벤트](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-events.html)를 수신하여 0개 이상의 목적지 또는 *대상*에 전달하는 라우터입니다.[ 이벤트 버스와 연결된 규칙](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-rules.html)은 이벤트가 도착할 때 이벤트를 평가하여 처리를 위해 [대상](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-targets.html)에 보냅니다.

다음 아키텍처에서:
+ 주문 서비스, 재고 서비스, 결제 서비스 등의 마이크로서비스는 Lambda 함수로 구현됩니다.
+ 사용자 지정 EventBridge 버스는 `Orders` 이벤트 버스, `Inventory` 이벤트 버스, `Payment` 이벤트 버스 등 세 가지가 있습니다.
+ `Orders` 규칙, `Inventory` 규칙 및 `Payment` 규칙은 해당 이벤트 버스로 전송된 이벤트를 매칭하고 Lambda 함수를 간접적으로 호출합니다.

![\[AWS 서비스를 사용한 Saga 코레오그래피 아키텍처\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/cloud-design-patterns/images/saga-choreography-2.png)


성공적인 시나리오에서 주문이 접수되면:

1. 주문 서비스가 요청을 처리하고 이벤트를 `Orders` 이벤트 버스로 보냅니다.

1. `Orders` 규칙이 이벤트를 매칭하고 재고 서비스를 시작합니다.

1. 재고 서비스가 인벤토리를 업데이트하고 이벤트를 `Inventory` 이벤트 버스로 보냅니다.

1. `Inventory` 규칙이 이벤트를 매칭하고 결제 서비스를 시작합니다.

1. 결제 서비스가 결제를 처리하고 이벤트를 `Payment` 이벤트 버스로 보냅니다.

1. `Payment` 규칙이 이벤트와 매칭하고 리스너로 `Payment processed` 이벤트 알림을 보냅니다.

   또는 주문 처리에 문제가 있는 경우 EventBridge 규칙은 데이터 일관성과 무결성을 유지하기 위해 데이터 업데이트를 되돌리는 보정 트랜잭션을 시작합니다.

1. 결제가 실패하면 `Payment` 규칙이 이벤트를 처리하고 재고 서비스를 시작합니다. 재고 서비스가 보정 트랜잭션을 실행하여 재고를 되돌립니다.

1. 재고가 되돌려지면 재고 서비스가 `Inventory reverted` 이벤트를 `Inventory` 이벤트 버스로 보냅니다. 이 이벤트는 `Inventory` 규칙에 따라 처리됩니다. 주문 서비스가 시작되며, 이 서비스는 보정 트랜잭션을 실행하여 주문을 제거합니다.

## 관련 콘텐츠
<a name="saga-choreography-resources"></a>
+ [Saga 오케스트레이션 패턴](saga-orchestration.md)
+ [트랜잭션 아웃박스 패턴](transactional-outbox.md)
+ [백오프 패턴으로 재시도](retry-backoff.md)