기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
Saga 코레오그래피 패턴
의도
Saga 코레오그래피 패턴은 이벤트 구독을 사용하여 여러 서비스에 걸친 분산 트랜잭션에서 데이터 무결성을 유지하는 데 도움이 됩니다. 분산 트랜잭션에서는 트랜잭션이 완료되기 전에 여러 서비스를 직접적으로 호출할 수 있습니다. 서비스가 여러 데이터 스토어에 데이터를 저장하는 경우 이러한 데이터 스토어 전반에서 데이터 일관성을 유지하기가 어려울 수 있습니다.
목적
트랜잭션은 여러 단계를 포함할 수 있는 단일 작업 단위로, 모든 단계가 완전히 실행되거나 어떤 단계도 실행되지 않기 때문에 데이터 스토어의 일관된 상태가 유지됩니다. 원자성, 일관성, 격리 및 내구성(ACID)이라는 용어로 트랜잭션의 속성이 정의됩니다. 관계형 데이터베이스는 데이터 일관성을 유지하기 위해 ACID 트랜잭션을 제공합니다.
트랜잭션의 일관성을 유지하기 위해 관계형 데이터베이스는 2단계 커밋(2PC) 방식을 사용합니다. 이는 준비 단계와 커밋 단계로 구성됩니다.
-
준비 단계에서는 조정 프로세스를 통해 트랜잭션의 참여 프로세스(참가자)에 트랜잭션을 커밋 또는 롤백할 것을 약속하도록 요청합니다.
-
커밋 단계에서 조정 프로세스는 참가자에게 트랜잭션을 커밋하도록 요청합니다. 참가자가 준비 단계에서 커밋에 동의하지 않으면 트랜잭션이 롤백됩니다.
database-per-service 설계 패턴을 따르는 분산 시스템에서는 2단계 커밋이 선택 사항이 아닙니다. 이는 각 트랜잭션이 다양한 데이터베이스에 분산되어 있고 관계형 데이터 스토어의 2단계 커밋과 유사한 프로세스를 조정할 수 있는 단일 컨트롤러가 없기 때문입니다. 이 경우 해결 방법 중 하나는 Saga 코레오그래피 패턴을 사용하는 것입니다.
적용 가능성
다음과 같은 경우에 Saga 코레오그래피 패턴을 사용합니다.
-
시스템에서 여러 데이터 스토어에 걸친 분산 트랜잭션의 데이터 무결성과 일관성이 요구됩니다.
-
데이터 스토어(예: NoSQL 데이터베이스)는 ACID 트랜잭션을 제공하기 위한 2PC를 제공하지 않으므로, 단일 트랜잭션 내에서 여러 테이블을 업데이트해야 하며 애플리케이션 경계 내에서 2PC를 구현하기가 복잡합니다.
-
참가자 트랜잭션을 관리하는 중앙 제어 프로세스가 단일 장애 지점이 될 수 있습니다.
-
Saga 참가자는 독립적인 서비스이므로 느슨하게 결합되어야 합니다.
-
비즈니스 도메인의 제한된 컨텍스트 간에 커뮤니케이션이 이루어집니다.
문제 및 고려 사항
-
복잡성: 마이크로서비스의 수가 증가하면 마이크로서비스 간의 상호 작용이 많아져 Saga 코레오그래피를 관리하기가 어려워질 수 있습니다. 또한 보정 트랜잭션 및 재시도로 인해 애플리케이션 코드의 복잡성이 가중되어 유지 관리 오버헤드를 초래할 수 있습니다. 코레오그래피는 Saga의 참가자가 소수에 불과하고 단일 장애 지점이 없는 간단한 구현이 필요한 경우에 적합합니다. 참가자가 더 추가되면 이 패턴을 사용하여 참가자 간의 종속성을 추적하기가 더 어려워집니다.
-
탄력적인 구현: Saga 코레오그래피에서는 시간 초과, 재시도 및 기타 복원력 패턴을 전반적으로 구현하기가 Saga 오케스트레이션에 비해 더 어렵습니다. 코레오그래피는 오케스트레이터 수준이 아닌 개별 구성 요소에 구현되어야 합니다.
-
주기적 종속성: 참가자들은 서로가 게시한 메시지를 소비합니다. 이로 인해 주기적 종속성이 발생하여 코드 복잡성과 유지 관리 오버헤드가 발생하고 교착 상태가 발생할 수 있습니다.
-
이중 쓰기 문제: 마이크로서비스는 데이터베이스를 자동으로 업데이트하고 이벤트를 게시해야 합니다. 두 작업 중 하나가 실패하면 상태가 일관되지 않을 수 있습니다. 이 문제를 해결하는 방법 중 하나는 트랜잭션 아웃박스 패턴을 사용하는 것입니다.
-
이벤트 보존: Saga 참가자들은 게시된 이벤트에 따라 작동합니다. 감사, 디버깅 및 재생을 위해 이벤트를 발생한 순서대로 저장하는 것이 중요합니다. 데이터 일관성을 복원하기 위해 시스템 상태를 재생해야 하는 경우 이벤트 소싱 패턴을 사용하여 이벤트 스토어에 이벤트를 유지할 수 있습니다. 이벤트 스토어는 시스템의 모든 변경 사항을 반영하므로 감사 및 문제 해결 목적으로도 사용할 수 있습니다.
-
최종 일관성: 로컬 트랜잭션을 순차적으로 처리하면 최종 일관성이 유지되며, 이는 강력한 일관성이 필요한 시스템에서는 까다로운 과제가 될 수 있습니다. 정합성 모델에 대한 비즈니스 팀의 기대치를 설정하거나 사용 사례를 재평가하여 강력한 일관성을 제공하는 데이터베이스로 전환함으로써 이 문제를 해결할 수 있습니다.
-
멱등성: Saga 참가자는 예상치 못한 충돌 및 오케스트레이터 장애로 인한 일시적 장애 발생 시, 반복 실행을 허용할 수 있는 멱등성을 갖추어야 합니다.
-
트랜잭션 격리: Saga 패턴은 ACID 트랜잭션의 네 가지 속성 중 하나인 트랜잭션 격리를 지원하지 않습니다. 트랜잭션의 격리 정도에 따라 다른 동시 트랜잭션이 기반이 되는 데이터에 어느 정도 영향을 미칠 수 있는지 결정됩니다. 트랜잭션을 동시에 오케스트레이션하면 데이터가 부실해질 수 있습니다. 이러한 시나리오를 처리하려면 시맨틱 잠금을 사용하는 것이 좋습니다.
-
관찰성: 관찰성이란 구현 및 오케스트레이션 프로세스의 문제를 해결하기 위한 상세한 로깅과 추적을 의미합니다. 이는 Saga 참가자 수가 증가하여 디버깅이 복잡해질 경우에 중요해집니다. 사가 오케스트레이션에 비해 사가 안무에서는 E nd-to-end 모니터링 및 보고가 더 어렵습니다.
-
지연 문제: Saga가 여러 단계로 구성된 경우 보정 트랜잭션으로 인해 전체 응답 시간에서 지연 시간이 늘어날 수 있습니다. 트랜잭션이 동기식으로 직접 호출을 수행하는 경우 지연 시간이 더 늘어날 수 있습니다.
구현
전반적인 아키텍처
다음 아키텍처 다이어그램에서 Saga 코레오그래피에는 주문 서비스, 인벤토리 서비스, 결제 서비스라는 세 가지 참가자가 참여합니다. 트랜잭션을 완료하려면 T1, T2, T3의 세 단계가 필요합니다. 세 가지 보정 트랜잭션은 데이터를 초기 상태(C1, C2, C3)로 복원합니다.
![전반적인 Saga 코레오그래피 아키텍처](images/saga-choreography-1.png)
-
주문 서비스는 데이터베이스를 자동으로 업데이트하고 메시지 브로커에
Order placed
메시지를 게시하는 로컬 트랜잭션 T1을 실행합니다. -
재고 서비스는 주문 서비스 메시지를 구독하고 주문이 생성되었다는 메시지를 받습니다.
-
재고 서비스는 데이터베이스를 자동으로 업데이트하고 메시지 브로커에
Inventory updated
메시지를 게시하는 로컬 트랜잭션 T2를 실행합니다. -
결제 서비스는 재고 서비스의 메시지를 구독하고 재고가 업데이트되었다는 메시지를 수신합니다.
-
결제 서비스는 데이터베이스에서 결제 세부 정보를 자동으로 업데이트하고 메시지 브로커에
Payment processed
메시지를 게시하는 로컬 트랜잭션 T3를 실행합니다. -
결제가 실패하면 결제 서비스는 보정 트랜잭션인 C1을 실행합니다. 이 트랜잭션은 데이터베이스의 결제를 원자적으로 되돌리고 메시지 브로커에
Payment failed
메시지를 게시합니다. -
보상 트랜잭션 C2와 C3은 데이터 일관성을 복원하기 위해 실행됩니다.
AWS 서비스를 사용한 구현
Amazon을 사용하여 사가 안무 패턴을 구현할 수 있습니다. EventBridge EventBridge이벤트를 사용하여 애플리케이션 구성 요소를 연결합니다. 그리고 이벤트 버스 또는 파이프를 통해 이벤트를 처리합니다. 이벤트 버스는 이벤트를 수신하여 0개 이상의 목적지 또는 대상에 전달하는 라우터입니다. 이벤트 버스와 연결된 규칙은 이벤트가 도착할 때 이벤트를 평가하여 처리를 위해 대상에 보냅니다.
다음 아키텍처에서:
-
주문 서비스, 재고 서비스, 결제 서비스 등의 마이크로서비스는 Lambda 함수로 구현됩니다.
-
커스텀 EventBridge 버스에는 이벤트 버스,
Orders
이벤트 버스,Inventory
이벤트 버스의 세 가지가 있습니다.Payment
-
Orders
규칙,Inventory
규칙 및Payment
규칙은 해당 이벤트 버스로 전송된 이벤트를 매칭하고 Lambda 함수를 간접적으로 호출합니다.
![AWS 서비스를 사용한 Saga 코레오그래피 아키텍처](images/saga-choreography-2.png)
성공적인 시나리오에서 주문이 접수되면:
-
주문 서비스가 요청을 처리하고 이벤트를
Orders
이벤트 버스로 보냅니다. -
Orders
규칙이 이벤트를 매칭하고 재고 서비스를 시작합니다. -
재고 서비스가 인벤토리를 업데이트하고 이벤트를
Inventory
이벤트 버스로 보냅니다. -
Inventory
규칙이 이벤트를 매칭하고 결제 서비스를 시작합니다. -
결제 서비스가 결제를 처리하고 이벤트를
Payment
이벤트 버스로 보냅니다. -
Payment
규칙이 이벤트와 매칭하고 리스너로Payment processed
이벤트 알림을 보냅니다.또는 주문 처리에 문제가 발생할 경우 EventBridge 규칙에 따라 보상 트랜잭션을 시작하여 데이터 업데이트를 되돌려 데이터 일관성과 무결성을 유지할 수 있습니다.
-
결제가 실패하면
Payment
규칙이 이벤트를 처리하고 재고 서비스를 시작합니다. 재고 서비스가 보정 트랜잭션을 실행하여 재고를 되돌립니다. -
재고가 되돌려지면 재고 서비스가
Inventory reverted
이벤트를Inventory
이벤트 버스로 보냅니다. 이 이벤트는Inventory
규칙에 따라 처리됩니다. 주문 서비스가 시작되며, 이 서비스는 보정 트랜잭션을 실행하여 주문을 제거합니다.