

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

# 데이터 지속성 활성화 패턴
<a name="enabling-patterns"></a>

 다음 패턴은 마이크로서비스에서 데이터 지속성을 활성화하는 데 사용됩니다.

**Topics**
+ [서비스별 데이터베이스 패턴](database-per-service.md)
+ [API 구성 패턴](api-composition.md)
+ [CQRS 패턴](cqrs-pattern.md)
+ [이벤트 소싱 패턴](service-per-team.md)
+ [Saga pattern](saga-pattern.md)
+ [서비스별 공유 데이터베이스 패턴](shared-database.md)

# 서비스별 데이터베이스 패턴
<a name="database-per-service"></a>

느슨한 결합은 마이크로서비스 아키텍처의 핵심 특징입니다. 이를 통해 개별 마이크로서비스가 독립적으로 자체 데이터 저장소에서 정보를 저장하고 검색할 수 있기 때문입니다. 서비스별 데이터베이스 패턴을 배포하면 애플리케이션 및 비즈니스 요구 사항에 가장 적합한 데이터 저장소(예: 관계형 또는 비관계형 데이터베이스)를 선택할 수 있습니다. 즉, 마이크로서비스는 데이터 계층을 공유하지 않고, 마이크로서비스의 개별 데이터베이스를 변경해도 다른 마이크로서비스에 영향을 주지 않으며, 개별 데이터 저장소에 다른 마이크로서비스가 직접 액세스할 수 없으며, 영구 데이터는 API로만 액세스할 수 있습니다. 또한 데이터 저장소를 분리하면 전체 애플리케이션의 복원력이 향상되고 단일 데이터베이스가 단일 장애 지점이 되지 않도록 할 수 있습니다.

다음 그림에서는 “판매”, “고객” 및 “규정 준수” 마이크로서비스에서 다양한 AWS 데이터베이스를 사용합니다. 이러한 마이크로서비스는 함수로 AWS Lambda 배포되고 Amazon API Gateway API를 통해 액세스됩니다. AWS Identity and Access Management (IAM) 정책은 데이터가 비공개로 유지되고 마이크로서비스 간에 공유되지 않도록 합니다. 각 마이크로서비스는 개별 요구 사항을 충족하는 데이터베이스 유형을 사용합니다. 예를 들어 ‘판매’는 Amazon Aurora를 사용하고, ‘고객’은 Amazon DynamoDB를, ‘규정 준수’는 Amazon Relational Database Service(Amazon RDS) for SQL Server를 사용합니다.

![\[서비스별 데이터베이스 패턴 다이어그램\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/modernization-data-persistence/images/enabling-diagram1.png)


다음과 같은 경우에는 이 패턴을 사용하는 것이 좋습니다.
+ 마이크로서비스 간에 느슨한 결합이 필요합니다.
+ 마이크로서비스의 데이터베이스에 대한 규정 준수 또는 보안 요구 사항이 다릅니다.
+ 규모 조정에 대한 보다 세밀한 제어가 필요합니다.

서비스별 데이터베이스 패턴을 사용하면 다음과 같은 단점이 있습니다.
+ 여러 마이크로서비스 또는 데이터 저장소에 걸쳐 있는 복잡한 트랜잭션과 쿼리를 구현하는 것은 어려울 수 있습니다.
+ 여러 관계형 및 비관계형 데이터베이스를 관리해야 합니다.
+ 데이터 저장소는 [CAP 정리](https://www.ibm.com/cloud/learn/cap-theorem) 요구 사항, *일관성*, *가용성*, *파티션 내성* 중에서 두 가지를 충족해야 합니다.

**참고**  
서비스별 데이터베이스 패턴을 사용하는 경우, 여러 마이크로서비스에 걸친 쿼리를 구현하려면 다른 패턴을 함께 배포해야 합니다. 집계 결과를 생성하기 위해 [API 구성 패턴](api-composition.md)(필요 시 [CQRS 패턴](cqrs-pattern.md)으로 속도 향상 가능) 또는 [이벤트 소싱 패턴](service-per-team.md)을 사용할 수 있습니다.

# API 구성 패턴
<a name="api-composition"></a>

이 패턴은 API 컴포저 또는 애그리게이터를 사용하여 데이터를 소유하는 개별 마이크로서비스를 호출하여 쿼리를 구현합니다. 그런 다음 인 메모리 조인을 수행하여 결과를 결합합니다.

다음 다이어그램은 이 패턴이 구현되는 방식을 보여 줍니다.

![\[API 구성 패턴 다이어그램\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/modernization-data-persistence/images/enabling-diagram2.png)


이 다이어그램은 다음 워크플로를 보여줍니다.

1. API Gateway는 Aurora 데이터베이스에서 고객 주문을 추적하는 ‘주문’ 마이크로서비스가 있는 ‘/customer’ API를 제공합니다.

1. ‘지원’ 마이크로서비스는 고객 지원 문제를 추적하여 Amazon OpenSearch Service 데이터베이스에 저장합니다.

1. ‘CustomerDetails’ 마이크로서비스는 DynamoDB 테이블의 고객 속성(예: 주소, 전화번호 또는 결제 세부 정보)을 유지 관리합니다.

1. ‘GetCustomer’ Lambda 함수는 이러한 마이크로서비스에 대한 API를 실행하고 데이터를 요청자에게 반환하기 전에 데이터에 대한 인 메모리 조인을 수행합니다. 이를 통해 사용자 대면 API에 대한 네트워크 호출 한 번으로 고객 정보를 쉽게 검색할 수 있으며 인터페이스가 매우 단순해집니다.

API 구성 패턴은 여러 마이크로서비스에서 데이터를 수집하는 가장 간단한 방법을 제공합니다. 하지만 API 구성 패턴을 사용하면 다음과 같은 단점이 있습니다.
+ 복잡한 쿼리와 인 메모리 조인이 필요한 대규모 데이터세트에는 적합하지 않을 수 있습니다.
+ API 컴포저에 연결된 마이크로서비스의 수를 늘리면 전체 시스템의 가용성이 떨어집니다.
+ 데이터베이스 요청이 증가하면 네트워크 트래픽 또한 증가하여, 운영 비용이 증가합니다.

# CQRS 패턴
<a name="cqrs-pattern"></a>

CQRS(명령 쿼리 책임 분리) 패턴은 데이터 변형 또는 시스템의 명령 부분을 쿼리 부분과 분리합니다. 처리량, 지연 시간 또는 일관성에 대한 요구 사항이 서로 다른 경우 CQRS 패턴을 사용하여 업데이트와 쿼리를 분리할 수 있습니다. CQRS 패턴은 다음 그림과 같이 애플리케이션을 명령 측과 쿼리 측의 두 부분으로 나눕니다. 명령 측은 `create`, `update`, `delete` 요청을 처리합니다. 쿼리 측에서는 읽기 전용 복제본을 사용하여 `query` 부분을 실행합니다.

![\[CQRS 패턴의 개괄적인 보기\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/modernization-data-persistence/images/cqrs.png)


이 다이어그램은 다음 프로세스를 보여줍니다.

1. 비즈니스는 API를 통해 명령을 전송하여 애플리케이션과 상호 작용합니다. 명령은 데이터 생성, 업데이트 또는 삭제와 같은 작업입니다.

1. 애플리케이션은 명령 측에서 들어오는 명령을 처리합니다. 이 과정에는 검증, 권한 부여, 연산 실행이 포함됩니다.

1. 애플리케이션은 명령 데이터를 쓰기(명령) 데이터베이스에 저장합니다.

1. 명령이 쓰기 데이터베이스에 저장된 후, 이벤트가 트리거되어 읽기(쿼리) 데이터베이스의 데이터를 업데이트합니다.

1. 읽기(쿼리) 데이터베이스는 데이터를 처리하고 저장합니다. 읽기 데이터베이스는 특정 쿼리 요구 사항에 최적화되도록 설계됩니다.

1. 비즈니스는 읽기 API를 통해 애플리케이션의 쿼리 측에 쿼리를 전송합니다.

1. 애플리케이션은 쿼리 측에서 들어오는 쿼리를 처리하고 읽기 데이터베이스에서 데이터를 가져옵니다.

CQRS 패턴은 다음과 같은 다양한 데이터베이스 조합으로 구현할 수 있습니다.
+ 명령 측과 쿼리 측 모두에 관계형 데이터베이스(RDBMS)를 사용하는 경우. 쓰기 작업은 기본 데이터베이스로, 읽기 작업은 읽기 복제본으로 라우팅할 수 있습니다. 예: [Amazon RDS 읽기 전용 복제본](https://aws.amazon.com/rds/features/read-replicas/)
+ 명령 측에 RDBMS, 쿼리 측에 NoSQL 데이터베이스를 사용하는 경우. 예: [에서 이벤트 소싱 및 CQRS를 사용하여 레거시 데이터베이스 현대화 AWS DMS](https://aws.amazon.com/blogs/database/modernize-legacy-databases-using-event-sourcing-and-cqrs-with-aws-dms/)
+ 명령 측과 쿼리 측 모두에 NoSQL 데이터베이스를 사용하는 경우. 예: [Amazon DynamoDB로 CQRS 이벤트 스토어 구축](https://aws.amazon.com/blogs/database/build-a-cqrs-event-store-with-amazon-dynamodb/)
+ 다음 예제에서 설명한 대로 명령 측에 NoSQL 데이터베이스, 쿼리 측에 RDBMS 데이터베이스를 사용하는 경우.

다음 그림에서는 DynamoDB와 같은 NoSQL 데이터 저장소를 사용하여 쓰기 처리량을 최적화하고 유연한 쿼리 기능을 제공합니다. 따라서 데이터를 추가할 때 액세스 패턴이 잘 정의된 워크로드에서 쓰기 확장성이 향상됩니다. Amazon Aurora와 같은 관계형 데이터베이스는 복잡한 쿼리 기능을 제공합니다. DynamoDB 스트림은 Aurora 테이블을 업데이트하는 Lambda 함수로 데이터를 전송합니다.

![\[AWS 서비스로 구현된 CQRS 패턴\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/modernization-data-persistence/images/enabling-diagram3.png)


DynamoDB와 Aurora를 사용하여 CQRS 패턴을 구현하면 다음과 같은 주요 이점이 있습니다.
+ DynamoDB는 대량 쓰기 작업을 처리할 수 있는 완전 관리형 NoSQL 데이터베이스이며, Aurora는 쿼리 측에서 복잡한 쿼리에 대해 높은 읽기 확장성을 제공합니다.
+ DynamoDB는 짧은 지연 시간과 많은 처리량으로 데이터를 제공하므로 명령 및 업데이트 작업 처리에 적합하며, Aurora는 복잡한 쿼리에 대해 성능을 세밀하게 조정하고 최적화할 수 있습니다.
+ DynamoDB와 Aurora 모두 서버리스 옵션을 제공하므로, 사용한 리소스에 대해서만 비용을 지불할 수 있습니다.
+ DynamoDB와 Aurora는 완전 관리형 서비스이므로 데이터베이스 관리, 백업, 확장성에 따른 운영 부담을 줄일 수 있습니다.

다음과 같은 경우에는 CQRS 패턴을 사용하는 것이 좋습니다.
+ 서비스별 데이터베이스 패턴을 구현했고 여러 마이크로서비스의 데이터를 조인하려고 합니다.
+ 읽기 및 쓰기 워크로드에는 규모 조정, 지연 시간 및 일관성에 대한 별도의 요구 사항이 있습니다.
+ 최종 일관성은 읽기 쿼리에 사용할 수 있습니다.

**중요**  
CQRS 패턴은 일반적으로 데이터 저장소 간의 최종 일관성을 초래합니다.

# 이벤트 소싱 패턴
<a name="service-per-team"></a>

이벤트 소싱 패턴은 일반적으로 [CQRS 패턴](cqrs-pattern.md)과 함께 사용하여 읽기 워크로드와 쓰기 워크로드를 분리하고 성능, 확장성 및 보안을 최적화합니다. 데이터는 데이터 저장소에 직접 업데이트되는 대신 일련의 이벤트로 저장됩니다. 마이크로서비스는 이벤트 저장소의 이벤트를 재생하여 자체 데이터 저장소의 적절한 상태를 계산합니다. 이 패턴은 애플리케이션의 현재 상태에 대한 가시성과 애플리케이션이 어떻게 해당 상태에 도달했는지에 대한 추가 컨텍스트를 제공합니다. 명령 및 쿼리 데이터 저장소의 스키마가 다르더라도 특정 이벤트에 대한 데이터를 복제할 수 있기 때문에 이벤트 소싱 패턴은 CQRS 패턴과 효과적으로 작동합니다.

이 패턴을 선택하면 특정 시점의 애플리케이션 상태를 식별하고 재구성할 수 있습니다. 이를 통해 지속적인 감사 추적이 생성되고 디버깅이 더 쉬워집니다. 그러나 데이터는 결국 일관성을 가지게 되므로 일부 사용 사례에는 적합하지 않을 수 있습니다.

이 패턴은 Amazon Kinesis Data Streams 또는 Amazon EventBridge를 사용하여 구현할 수 있습니다.

## Amazon Kinesis Data Streams 구현
<a name="amazon-kinesis"></a>

다음 그림에서 Kinesis Data Streams는 중앙 집중식 이벤트 저장소의 주요 구성 요소입니다. 이벤트 저장소는 애플리케이션 변경 사항을 이벤트로 캡처하여 Amazon Simple Storage Service(Amazon S3)에 유지합니다.

![\[Amazon Kinesis Data Streams 구현\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/modernization-data-persistence/images/enabling-diagram4.png)


워크플로우는 다음 단계로 구성됩니다.

1. ‘/withdraw’ 또는 ‘/credit’ 마이크로서비스에서 이벤트 상태 변경이 발생하면 Kinesis Data Streams에 메시지를 작성하여 이벤트를 게시합니다.

1. ‘/balance’ 또는 ‘/creditLimit’과 같은 기타 마이크로서비스는 메시지 사본을 읽고 관련성을 기준으로 필터링한 다음 추가 처리를 위해 전달합니다.

## Amazon EventBridge 구현
<a name="amazon-eventbridge"></a>

다음 그림의 아키텍처는 EventBridge를 사용합니다. EventBridge는 이벤트를 사용하여 애플리케이션 구성 요소를 연결하는 서버리스 서비스로, 이를 통해 확장 가능한 이벤트 기반 애플리케이션을 쉽게 구축할 수 있습니다. 이벤트 기반 아키텍처는 이벤트를 발생시키고 이에 응답함으로써 느슨하게 결합된 소프트웨어 시스템을 구축하는 방식입니다. EventBridge는 AWS 서비스에서 게시하는 이벤트에 대한 [기본 이벤트 버스](https://docs.aws.amazon.com//eventbridge/latest/userguide/create-event-bus.html)를 제공하며 도메인별 버스에 대한 [사용자 지정 이벤트](https://docs.aws.amazon.com//eventbridge/latest/userguide/create-event-bus.html) 버스를 생성할 수도 있습니다.

![\[Amazon EventBridge 구현\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/modernization-data-persistence/images/enabling-diagram5.png)


워크플로우는 다음 단계로 구성됩니다.

1. ‘OrderPlaced’ 이벤트는 ‘Orders’ 마이크로서비스에 의해 사용자 지정 이벤트 버스에 게시됩니다.

1. ‘/route’ 마이크로서비스와 같이 주문 후 조치를 취해야 하는 마이크로서비스는 규칙과 대상에 따라 시작됩니다.

1. 이러한 마이크로서비스는 주문을 고객에게 배송하는 경로를 생성하고 ‘RouteCreated’ 이벤트를 발생시킵니다.

1. 추가 조치가 필요한 마이크로서비스도 ‘RouteCreated’ 이벤트에 의해 시작됩니다.

1. 이벤트는 필요한 경우 재처리를 위해 재생할 수 있도록 이벤트 아카이브(예: EventBridge 아카이브)로 전송됩니다.

1. 과거 주문 이벤트는 필요 시 재처리를 위해 새로운 Amazon SQS 대기열(재생 대기열)로 전송됩니다.

1. 대상이 시작되지 않은 경우 영향을 받는 이벤트는 추가 분석 및 재처리를 위해 배달 못한 편지 대기열(DLQ)에 배치됩니다.

다음과 같은 경우에는 이 패턴을 사용하는 것이 좋습니다.
+ 이벤트는 애플리케이션 상태를 완전히 재구축하는 데 사용됩니다.
+ 시스템에서 이벤트를 재생해야 하며 언제든지 애플리케이션 상태를 확인할 수 있어야 합니다.
+ 빈 애플리케이션 상태로 시작하지 않고도 특정 이벤트를 되돌릴 수 있기를 원합니다.
+ 시스템에는 자동 로그를 생성하기 위해 쉽게 직렬화할 수 있는 이벤트 스트림이 필요합니다.
+ 시스템에는 많은 읽기 작업이 필요하지만 쓰기 작업은 적습니다. 따라서 읽기 작업이 많으면 이벤트 스트림으로 계속 업데이트되는 인 메모리 데이터베이스로 보낼 수 있습니다.

**중요**  
이벤트 소싱 패턴을 사용하는 경우 마이크로서비스 전반에서 데이터 일관성을 유지하기 위해 [Saga pattern](saga-pattern.md)을 배포해야 합니다.

# Saga pattern
<a name="saga-pattern"></a>

saga 패턴은 분산 애플리케이션의 일관성을 유지하고 여러 마이크로서비스 간의 트랜잭션을 조정하여 데이터 일관성을 유지하는 데 도움이 되는 장애 관리 패턴입니다. 마이크로서비스는 모든 트랜잭션에 대한 이벤트를 게시하고, 이벤트 결과에 따라 다음 트랜잭션이 시작됩니다. 트랜잭션의 성공 또는 실패에 따라 두 가지 경로를 사용할 수 있습니다.

다음 그림은 saga 패턴이 AWS Step Functions을 사용하여 주문 처리 시스템을 구현하는 방법을 보여줍니다. 또한 각 단계(예: ‘ProcessPayment’)에는 프로세스의 성공(예: ‘UpdateCustomerAccount’) 또는 실패(예: ‘SetOrderFailure’)를 처리하기 위한 별도의 단계가 있습니다.

![\[Saga pattern\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/modernization-data-persistence/images/enabling-diagram6.png)


다음과 같은 경우에는 이 패턴을 사용하는 것이 좋습니다.
+ 애플리케이션은 긴밀한 결합 없이 여러 마이크로서비스 전반에서 데이터 일관성을 유지해야 합니다.
+ 트랜잭션은 오래 지속되므로 한 마이크로서비스가 오랫동안 실행되더라도 다른 마이크로서비스가 차단되는 것을 원하지 않을 것입니다.
+ 정해진 순서에 따라 작업이 실패하더라도 롤백할 수 있어야 합니다.

**중요**  
saga 패턴은 디버깅하기 어렵고 마이크로서비스가 많아질수록 복잡성이 증가합니다. 이 패턴에는 롤백 및 변경 실행 취소를 위한 보상 트랜잭션을 개발하고 설계하는 복잡한 프로그래밍 모델이 필요합니다.

마이크로서비스 아키텍처에서 saga 패턴을 구현하는 방법에 대한 자세한 내용은 AWS 권장 가이드 웹사이트에서 [AWS Step Functions을 사용한 서버리스 saga 패턴의 구현](https://docs.aws.amazon.com//prescriptive-guidance/latest/patterns/implement-the-serverless-saga-pattern-by-using-aws-step-functions.html) 패턴을 참조하세요.

# 서비스별 공유 데이터베이스 패턴
<a name="shared-database"></a>

서비스별 공유 데이터베이스 패턴에서는 여러 마이크로서비스가 동일한 데이터베이스를 공유합니다. 이 패턴을 채택하기 전에 애플리케이션 아키텍처를 신중히 평가하고, 여러 마이크로서비스가 동시에 쓰기를 수행하는 단일 테이블(핫 테이블)을 피해야 합니다. 또한 모든 데이터베이스 변경 사항은 하위 버전과 호환되어야 합니다. 예를 들어 개발자는 모든 마이크로서비스의 최신 및 이전 버전에서 객체를 참조하지 않는 경우에만 열이나 테이블을 삭제할 수 있습니다.

다음 그림에서 모든 마이크로서비스가 보험 데이터베이스를 공유하고 있으며 IAM 정책은 이 데이터베이스에 대한 액세스를 제공합니다. 이로 인해 개발 시간이 결합됩니다. 예를 들어, ‘판매’ 마이크로서비스를 변경하면 ‘고객’ 마이크로서비스와 스키마 변경을 조정해야 합니다. 이 패턴은 개발 팀 간의 종속성을 줄이지 않으며 모든 마이크로서비스가 동일한 데이터베이스를 공유하기 때문에 런타임 결합을 도입합니다. 예를 들어 장기간 실행되는 ‘판매’ 트랜잭션은 ‘고객’ 테이블을 잠글 수 있으며 이로 인해 ‘고객’ 트랜잭션이 차단될 수 있습니다.

![\[서비스별 공유 데이터베이스 패턴\]](http://docs.aws.amazon.com/ko_kr/prescriptive-guidance/latest/modernization-data-persistence/images/enabling-diagram7.png)


다음과 같은 경우에는 이 패턴을 사용하는 것이 좋습니다.
+ 기존 코드베이스를 너무 많이 리팩터링하고 싶지는 않을 것입니다.
+ 원자성, 일관성, 격리 및 내구성(ACID)을 제공하는 트랜잭션을 사용하여 데이터 일관성을 유지합니다.
+ 데이터베이스를 하나만 유지 관리하고 운영하려고 합니다.
+ 서비스별 데이터베이스 패턴을 구현하는 것은 기존 마이크로서비스 간의 상호 종속성 때문에 어렵습니다.
+ 기존 데이터 계층을 완전히 재설계하고 싶지는 않습니다.