Saga 디자인 패턴은 여러 서비스에서 트랜잭션을 조정하여 분산 시스템에서 데이터 일관성을 유지하는 데 도움이 됩니다. 사가는 각 서비스가 작업을 수행하고 이벤트 또는 메시지를 통해 다음 단계를 시작하는 로컬 트랜잭션의 시퀀스입니다. 시퀀스의 단계가 실패하면 사가는 보상 트랜잭션을 실행하여 완료된 단계를 실행 취소하고 데이터 일관성을 유지합니다.
컨텍스트 및 문제
트랜잭션 여러 작업을 포함할 수 있는 작업 단위를 나타냅니다. 트랜잭션 내에서 이벤트 엔터티에 영향을 주는 상태 변경을 나타냅니다. 명령 작업을 수행하거나 후속 이벤트를 트리거하는 데 필요한 모든 정보를 캡슐화합니다.
트랜잭션은 ACID(원자성, 일관성, 격리 및 내구성)의 원칙을 준수해야 합니다.
- 원자성: 모든 작업이 성공하거나 아무 작업도 수행하지 않습니다.
- 일관성: 데이터가 유효한 상태에서 다른 상태로 전환됩니다.
- 격리: 동시 트랜잭션은 순차 트랜잭션과 동일한 결과를 생성합니다.
- 내구성: 커밋된 후에는 오류가 발생하더라도 변경 내용이 유지됩니다.
단일 서비스에서 트랜잭션은 단일 데이터베이스 내에서 작동하기 때문에 ACID 원칙을 따릅니다. 그러나 여러 서비스에서 ACID 규정 준수를 달성하는 것은 더 복잡합니다.
마이크로 서비스 아키텍처의 과제
마이크로 서비스 아키텍처는 일반적으로 각 마이크로 서비스
- 각 서비스는 자체 데이터를 캡슐화합니다.
- 각 서비스는 특정 요구 사항에 가장 적합한 데이터베이스 기술 및 스키마를 사용할 수 있습니다.
- 각 서비스에 대한 데이터베이스의 독립적인 크기 조정
- 한 서비스의 오류는 다른 서비스와 격리됩니다.
이러한 장점에도 불구하고 이 아키텍처는 서비스 간 데이터 일관성을 복잡하게 만듭니다. ACID와 같은 기존 데이터베이스 보장은 독립적으로 관리되는 여러 데이터 저장소에 직접 적용되지 않습니다. 이러한 제한 사항으로 인해 IPC(Interprocess Communication) 또는 기존 트랜잭션 모델(예: 2단계 커밋) 프로토콜을 사용하는 아키텍처는 종종 Saga 패턴에 더 적합합니다.
용액
Saga 패턴은 트랜잭션을 일련의 로컬 트랜잭션 구분하여 관리합니다(그림 1참조).
사가 개요를 보여 주는
그림 1. 세 가지 서비스가 있는 무용담.
각 로컬 트랜잭션:
- 단일 서비스 내에서 원자성으로 작업을 완료합니다.
- 서비스의 데이터베이스를 업데이트합니다.
- 이벤트 또는 메시지를 통해 다음 트랜잭션을 시작합니다.
- 로컬 트랜잭션이 실패하면 사가는 일련의 보상 트랜잭션 실행하여 이전 로컬 트랜잭션의 변경 내용을 취소합니다.
Saga 패턴의 주요 개념
보상 가능한 트랜잭션: 다른 트랜잭션이 반대의 효과로 실행 취소하거나 보정할 수 있는 트랜잭션입니다. 사가의 단계가 실패하면 트랜잭션을 보상하면 보상 가능한 트랜잭션이 변경한 내용을 취소합니다.
피벗 트랜잭션: 피벗 트랜잭션은 사가에서 "반환되지 않는 지점"으로 사용됩니다. 피벗 트랜잭션이 성공하면 보상 가능한 트랜잭션(실행 취소할 수 있음)은 더 이상 관련이 없습니다. 시스템이 일관된 최종 상태를 달성하려면 모든 후속 작업이 완료되어야 합니다. 피벗 트랜잭션은 사가의 흐름에 따라 다른 역할에 속할 수 있습니다.
취소할 수 없음(비호환): 실행 취소하거나 다시 시도할 수 없습니다.
가역 및 커밋된간의 경계: 마지막으로 실행 취소할 수 있는(보상 가능한) 트랜잭션일 수도 있고, 사가에서 다시 시도할 수 있는 첫 번째 작업일 수도 있습니다.
다시 시도 가능한 트랜잭션: 이러한 트랜잭션은 피벗 트랜잭션을 따릅니다. 재시도 가능한 트랜잭션은 idempotent이며 임시 오류가 발생하더라도 사가가 최종 상태에 도달할 수 있는지 확인합니다. 그것은 무용담이 결국 일관된 상태를 달성한다는 것을 보장합니다.
Saga 구현 방법
안무 및
안무
안무에서 서비스는 중앙 집중식 컨트롤러 없이 이벤트를 교환합니다. 안무를 사용하여 각 로컬 트랜잭션은 다른 서비스에서 로컬 트랜잭션을 트리거하는 도메인 이벤트를 게시합니다(그림 2참조).
안무를 사용한 무용담을 보여주는
그림 2. 안무를 사용하는 무용담.
안무 |
안무 |
---|---|
서비스가 거의 없는 간단한 워크플로에 적합하며 조정 논리가 필요하지 않습니다. | 새 단계를 추가할 때 워크플로가 혼동될 수 있습니다. 어떤 사가 참가자가 어떤 명령을 듣는지 추적하기가 어렵습니다. |
조정을 위해 다른 서비스가 필요하지 않습니다. | 사가 참가자는 서로의 명령을 소비해야 하기 때문에 주기적 종속성의 위험이 있습니다. |
책임은 사가 참가자에게 분산되므로 단일 실패 지점을 도입하지 않습니다. | 트랜잭션을 시뮬레이션하기 위해 모든 서비스를 실행해야 하므로 통합 테스트가 어렵습니다. |
오케스트레이션
오케스트레이션에서 중앙 집중식 컨트롤러(오케스트레이터)는 모든 트랜잭션을 처리하고 이벤트에 따라 수행할 작업을 참가자에게 알려줍니다. 오케스트레이터는 사가 요청을 실행하고 각 작업의 상태를 저장 및 해석하며 보정 트랜잭션을 사용하여 오류 복구를 처리합니다(그림 3참조).
오케스트레이션을 사용하는 사가를 보여 주는
그림 3. 오케스트레이션을 사용하는 사가입니다.
오케스트레이션 |
오케스트레이션 |
---|---|
복잡한 워크플로 또는 새 서비스를 추가할 때 더 적합합니다. | 다른 디자인 복잡성에는 조정 논리를 구현해야 합니다. |
오케스트레이터가 흐름을 관리하기 때문에 순환 종속성을 방지합니다. | 오케스트레이터가 전체 워크플로를 관리하므로 실패 지점을 소개합니다. |
책임의 명확한 분리는 서비스 논리를 간소화합니다. |
문제 및 고려 사항
Saga 패턴을 구현할 때 다음 사항을 고려합니다.
디자인 사고변화: Saga 패턴을 채택하려면 트랜잭션을 조정하고 여러 마이크로 서비스에서 데이터 일관성을 보장하는 데 중점을 두는 다른 사고방식이 필요합니다.
사가 디버깅복잡성: 특히 참여 서비스 수가 증가함에 따라 사가 디버깅은 복잡할 수 있습니다.
되돌릴 수 없는 로컬 데이터베이스 변경: 사가 참가자가 해당 데이터베이스에 변경 내용을 커밋하므로 데이터를 롤백할 수 없습니다.
일시적인 오류 및 멱등처리: 시스템은 일시적인 오류를 효과적으로 처리하고 동일한 작업을 반복해도 결과가 변경되지 않는 멱등성을 확인해야 합니다. 자세한 내용은 Idempotent 메시지 처리참조하세요.
사가를 모니터링하고 추적해야 합니다. 운영 감독을 유지하려면 사가의 워크플로를 모니터링하고 추적해야 합니다.
트랜잭션 보상 제한: 트랜잭션 보상이 항상 성공하지 못할 수 있으므로 시스템이 일관되지 않은 상태로 남을 수 있습니다.
사가의 잠재적인 데이터 변칙
데이터 변칙은 여러 서비스에서 사가가 실행될 때 발생할 수 있는 불일치입니다. 각 서비스는 자체 데이터(참가자 데이터)를 관리하므로 서비스 간에 기본 제공 격리가 없습니다. 이 설정을 사용하면 부분적으로 적용된 업데이트 또는 서비스 간 충돌과 같은 데이터 불일치 또는 내구성 문제가 발생할 수 있습니다. 일반적인 문제는 다음과 같습니다.
분실 업데이트: 한 사가가 다른 사가의 변경 내용을 고려하지 않고 데이터를 수정하면 덮어쓰거나 누락된 업데이트가 발생합니다.
Dirty는읽습니다. 사가 또는 트랜잭션이 다른 사가가 수정했지만 아직 완료되지 않은 데이터를 읽을 때입니다.
유사 항목(재현할 수 없음) 읽기: 읽기 간에 업데이트가 발생하므로 사가의 다른 단계가 일관되지 않은 데이터를 읽을 때입니다.
데이터 변칙을 해결하기 위한 전략
이러한 변칙을 줄이거나 방지하려면 다음 대책을 고려하세요.
의미 체계 잠금: 사가의 보상 가능한 트랜잭션이 세마포를 사용하여 업데이트가 진행 중임을 나타내는 애플리케이션 수준 잠금을 사용합니다.
통근 업데이트: 업데이트를 디자인하여 동일한 결과를 생성하면서 순서에 따라 적용할 수 있도록 하여 사가 간의 충돌을 줄입니다.
비관적 보기: 데이터 업데이트가 다시 시도 가능한 트랜잭션에서 발생하도록 사가의 시퀀스를 다시 정렬하여 더티 읽기를 제거합니다. 그렇지 않으면 한 사가가 더티 데이터(커밋되지 않은 변경 내용)를 읽을 수 있는 반면, 다른 사가는 동시에 업데이트를 롤백하기 위해 보상 가능한 트랜잭션을 실행합니다.
값 다시 읽기: 업데이트하기 전에 데이터가 변경되지 않은 상태로 유지되도록 유효성을 검사합니다. 데이터가 변경되면 현재 단계를 중단하고 필요에 따라 사가를 다시 시작합니다.
버전 파일: 레코드에 대한 모든 작업의 로그를 유지하고 충돌을 방지하기 위해 올바른 순서로 실행되었는지 확인합니다.
위험 기반 동시성(값별): 잠재적인 비즈니스 위험에 따라 적절한 동시성 메커니즘을 동적으로 선택합니다. 예를 들어 위험 수준이 낮은 업데이트에 사가를 사용하고 위험 수준이 높은 업데이트에 분산 트랜잭션을 사용합니다.
이 패턴을 사용하는 경우
다음을 수행해야 하는 경우 Saga 패턴을 사용합니다.
- 긴밀한 결합 없이 분산 시스템에서 데이터 일관성을 보장합니다.
- 시퀀스의 작업 중 하나가 실패하면 롤백하거나 보정합니다.
Saga 패턴은 다음에 덜 적합합니다.
- 긴밀하게 결합된 트랜잭션.
- 이전 참가자에서 발생하는 보상 트랜잭션입니다.
- 순환 종속성입니다.
다음 단계
- 분산 데이터
- 리처드슨, 크리스. 2018: 마이크로 서비스 패턴. 매닝 출판물.
관련 리소스
다음 패턴은 이 패턴을 구현할 때도 유용할 수 있습니다.
- 안무 시스템의 각 구성 요소는 제어의 중심 지점에 의존하는 대신 비즈니스 트랜잭션의 워크플로에 대한 의사 결정 프로세스에 참여합니다.
- 트랜잭션 보상은 일련의 단계에서 수행된 작업을 실행 취소하고 하나 이상의 단계가 실패할 경우 일관된 작업을 정의할 있습니다. 복잡한 비즈니스 프로세스 및 워크플로를 구현하는 클라우드 호스팅 애플리케이션은 종종 이 최종 일관성 모델따릅니다.
- 다시 시도 실패한 작업을 투명하게 다시 시도하여 애플리케이션이 서비스 또는 네트워크 리소스에 연결하려고 할 때 일시적인 오류를 처리할 수 있습니다. 재시도는 애플리케이션의 안정성을 향상시킬 수 있습니다.
- 회로 차단기 원격 서비스 또는 리소스에 연결할 때 복구하는 데 가변적인 시간이 걸리는 오류를 처리합니다. 회로 차단기는 애플리케이션의 안정성과 복원력을 향상시킬 수 있습니다.
- 상태 엔드포인트 모니터링 외부 도구가 정기적으로 노출된 엔드포인트를 통해 액세스할 수 있는 애플리케이션의 기능 검사를 구현합니다. 상태 엔드포인트 모니터링은 애플리케이션 및 서비스가 올바르게 수행되고 있는지 확인하는 데 도움이 될 수 있습니다.