마이크로 서비스에 대한 데이터 고려 사항

Azure DevOps

이 아티클은 마이크로 서비스 아키텍처의 데이터를 관리하기 위한 고려 사항을 설명합니다. 모든 마이크로 서비스는 자체 데이터를 관리하기 때문에 데이터 무결성 및 데이터 일관성은 중요한 문제입니다.

마이크로 서비스의 기본 원리는 각 서비스가 자체 데이터를 관리하는 것입니다. 두 서비스는 데이터 저장소를 공유하면 안 됩니다. 대신 각 서비스는 다른 서비스가 직접 액세스할 수 없는 자체 프라이빗 데이터 저장소에 대한 책임이 있습니다.

이 규칙에 대한 이유는 서비스에서 동일한 기본 데이터 스키마를 공유하는 경우 발생할 수 있는 서비스 간의 의도하지 않은 결합을 방지하기 위해서입니다. 데이터 스키마에 대한 변경 내용이 있는 경우 해당 데이터베이스를 사용하는 모든 서비스에서 변경 내용이 조정되어야 합니다. 각 서비스의 데이터 저장소를 격리하여 변경의 범위를 제한하고 완전히 독립적인 배포의 민첩성을 유지할 수 있습니다. 다른 이유는 각 마이크로 서비스에 자체 데이터 모델, 쿼리 또는 읽기/쓰기 패턴이 있을 수 있기 때문입니다. 공유 데이터 스토리지를 사용하면 해당 특정 서비스에 대한 데이터 스토리지를 최적화하는 각 팀의 기능을 제한합니다.

Diagram of a wrong approach to CQRS

이 방법은 자연스럽게 다각적인 지속성 즉, 단일 애플리케이션 내의 여러 데이터 스토리지 기술의 사용으로 이어집니다. 하나의 서비스에는 문서 데이터베이스의 스키마 온 리드(schema-on-read) 기능이 필요할 수 있습니다. 다른 서비스에는 RDBMS에서 제공하는 참조 무결성이 필요할 수 있습니다. 각 팀은 자신의 서비스에 대한 최상의 선택을 할 수 있습니다.

참고 항목

서비스의 경우 동일한 물리적 데이터베이스 서버를 공유하는 것은 괜찮습니다. 서비스가 동일한 스키마를 공유하거나 동일한 데이터베이스 테이블 집합을 읽고 쓸 때 문제가 발생합니다.

과제

몇 가지 과제는 데이터 관리에 대한 이 분산된 방식에서 발생합니다. 먼저 여러 위치에 표시되는 동일한 데이터 항목이 있는 데이터 저장소에서 중복이 있을 수 있습니다. 예를 들어 데이터는 트랜잭션의 일부로 저장된 후 분석, 보고 또는 보관을 위해 다른 위치에 저장될 수 있습니다. 복제되거나 분할된 데이터로 인해 데이터 무결성과 일관성의 문제가 발생할 수 있습니다. 데이터 관계가 여러 서비스에 걸쳐 있는 경우 기존 데이터 관리 기법을 사용하여 관계를 적용할 수 없습니다.

기존 데이터 모델링은 "한 곳에 하나의 팩트" 규칙을 사용합니다. 모든 엔터티는 스키마에 정확히 한 번 나타납니다. 다른 엔터티는 이에 대한 참조를 저장할 수 있지만 복제할 수 없습니다. 기존의 접근 방식에 대한 명백한 장점은 데이터 일관성에 문제가 발생하지 않도록 한 위치에서 업데이트가 발생한다는 것입니다. 마이크로 서비스 아키텍처에서는 업데이트가 서비스 간에 전파되는 방법 및 강력한 일관성 없이 여러 위치에 데이터가 나타날 때 결과적 일관성을 관리하는 방법을 고려해야 합니다.

데이터를 관리하는 방법

모든 경우에 맞는 단일 접근 방식은 없지만 마이크로 서비스 아키텍처에서 데이터를 관리하기 위한 일반적인 지침은 다음과 같습니다.

  • 가능한 경우 결과적 일관성을 수용합니다. 강력한 일관성 또는 ACID 트랜잭션이 필요한 시스템의 위치 및 결과적 일관성이 허용되는 위치를 이해합니다.

  • 강력한 일관성 보장이 필요한 경우 하나의 서비스는 API를 통해 노출되는 특정 엔터티에 대한 정보의 원본을 나타낼 수 있습니다. 다른 서비스는 데이터의 자체 복사본 또는 결국 마스터 데이터와 일치하지만 정보의 원본으로 간주되지 않는 데이터의 하위 집합을 유지할 수도 있습니다. 예를 들어 고객 주문 서비스 및 권장 서비스를 사용하는 전자 상거래 시스템을 가정합니다. 권장 서비스는 주문 서비스에서 이벤트를 수신할 수 있지만 고객이 환불을 요청하는 경우 권장 서비스가 아닌 완전한 트랜잭션 기록이 있는 주문 서비스입니다.

  • 트랜잭션의 경우 Scheduler 에이전트 감독자보정 트랜잭션과 같은 패턴을 사용하여 여러 서비스에서 데이터 일관성을 유지합니다. 여러 서비스 간에 부분 장애를 방지하기 위해 여러 서비스에 걸쳐 있는 작업의 단위 상태를 캡처하는 데이터의 추가 부분을 저장해야 할 수도 있습니다. 예를 들어 다단계 트랜잭션이 진행 중인 동안 지속성 큐에서 작업 항목을 유지합니다.

  • 서비스가 필요한 데이터만 저장합니다. 서비스는 도메인 엔터티에 대한 정보의 하위 집합만 필요할 수 있습니다. 예를 들어 배송 제한된 컨텍스트에서 특정 배달에 연결된 고객을 알아야 합니다. 하지만 고객의 요금 청구서 주소가 필요하지 않습니다. 이는 계정 제한된 컨텍스트에서 관리됩니다. 도메인에 대해 신중하게 생각하세요. 여기에서는 DDD 방식을 사용하는 것이 도움이 될 수 있습니다.

  • 서비스가 일관적이고 느슨하게 결합되었는지 여부를 고려합니다. 두 서비스가 지속적으로 서로 정보를 교환하여 번잡한 API가 되는 경우 두 서비스를 병합하거나 해당 기능을 리팩터링하여 서비스 경계를 다시 그려야 할 수 있습니다.

  • 이벤트 기반 아키텍처 스타일을 사용합니다. 이 아키텍처 스타일에서 서비스는 해당 공용 모델 또는 엔터티에 변경 내용이 있을 때 이벤트를 게시합니다. 관심이 있는 서비스는 이러한 이벤트를 구독할 수 있습니다. 예를 들어 다른 서비스는 쿼리에 적합한 데이터의 구체화된 뷰를 생성하는 이벤트를 사용할 수 있습니다.

  • 이벤트를 소유하는 서비스는 게시자와 구독자 간의 긴밀한 결합을 방지하기 위해 이벤트 직렬화 및 역직렬화를 자동화하는 데 사용할 수 있는 스키마를 게시해야 합니다. JSON 스키마 또는 Microsoft Bond, Protobuf 또는 Avro와 같은 프레임워크를 사용하는 것이 좋습니다.

  • 큰 규모에서 이벤트는 시스템의 병목 지점이 될 수 있으므로 총 부하를 줄이도록 집계 또는 일괄 처리를 사용하는 것이 좋습니다.

예: 드론 배달 애플리케이션을 위한 데이터 저장소 선택

이 시리즈의 이전 아티클에서는 드론 배달 서비스를 실행 예제로 다룹니다. 시나리오 및 해당 참조 구현에 대한 자세한 내용은 여기에서 읽을 수 있습니다. 이 예제는 항공기 및 항공 우주 산업에 이상적입니다.

요약하자면, 이 애플리케이션은 드론에 의한 배달을 예약하기 위한 여러 마이크로 서비스를 정의합니다. 사용자가 새 배달을 예약하는 경우 클라이언트 요청에는 픽업 및 하차 위치와 같은 배달 관련 정보와 크기 및 무게와 같은 패키지 관련 정보가 포함됩니다. 이 정보는 작업 단위를 정의합니다.

다양한 백 엔드 서비스는 요청에서 서로 다른 정보의 부분에 대해 고려하며 서로 다른 읽기 및 쓰기 프로필을 갖습니다.

Diagram of data considerations

배달 서비스

배달 서비스는 현재 예약되어 있거나 진행 중인 모든 배달에 대한 정보를 저장합니다. 드론에서 이벤트에 대해 수신 대기하고 진행 중인 배달의 상태를 추적합니다. 또한 배달 상태 업데이트와 함께 도메인 이벤트를 보냅니다.

사용자는 해당 패키지를 기다리는 동안 배달 상태를 자주 확인할 수 있습니다. 따라서 배달 서비스는 장기 스토리지에 대해 처리량(읽기 및 쓰기)을 강조하는 데이터 스토리지가 필요합니다. 또한 배달 서비스는 복잡한 쿼리 또는 분석을 수행하지 않으며 단순히 지정된 배달에 대한 최신 상태를 페치합니다. 배달 서비스 팀은 높은 읽기-쓰기 성능을 위해 Azure Cache for Redis를 선택했습니다. Redis에 저장된 정보는 수명이 비교적 짧습니다. 배달이 완료되면 배달 기록 서비스는 레코드의 시스템입니다.

배달 기록 서비스

배달 기록 서비스는 배달 서비스의 배달 상태 이벤트에 대해 수신 대기합니다. 장기 스토리지에 이 데이터를 저장합니다. 서로 다른 데이터 스토리지 요구 사항이 있는 이 기록 데이터에 대한 두 개의 서로 다른 사용 사례가 있습니다.

첫 번째 시나리오는 비즈니스를 최적화하거나 서비스의 품질을 향상시키기 위해 데이터 분석의 목적으로 데이터를 집계합니다. 배달 기록 서비스는 데이터의 실제 분석을 수행하지 않습니다. 수집 및 스토리지만을 담당합니다. 이 시나리오의 경우 스토리지는 다양한 데이터 원본에 맞게 스키마 온 리드(schema-on-read) 방법을 사용하여 큰 데이터 세트에 대한 데이터 분석을 위해 최적화되어야 합니다. Azure Data Lake Store는 이 시나리오에 적합합니다. Data Lake Store는 HDFS(Hadoop 분산 파일 시스템)와 호환되는 Apache Hadoop 파일 시스템이며 데이터 분석 시나리오에 대한 성능을 위해 조정됩니다.

다른 시나리오는 사용자가 배달이 완료된 후 배달 기록을 조회할 수 있도록 합니다. Azure Data Lake는 이 시나리오에 최적화되지 않았습니다. 최적의 성능을 위해 날짜별로 분할된 폴더의 Data Lake에 시계열 데이터를 저장하는 것이 좋습니다. (성능을 위해 Azure Data Lake Store 조정을 참조하세요.) 그러나 해당 구조는 ID별 개별 레코드를 찾는 데 적합하지 않습니다. 또한 타임스탬프를 알 수 없다면 ID별 조회는 전체 컬렉션을 검색해야 합니다. 따라서 배달 기록 서비스도 빠른 조회를 위해 Azure Cosmos DB에 기록 데이터의 하위 집합을 저장합니다. 레코드는 Azure Cosmos DB에 무기한으로 유지될 필요가 없습니다. 이전 배달은 예를 들어 한 달 동안 보관될 수 있습니다. 간헐적인 일괄 처리 프로세스를 실행하여 수행할 수 있습니다. 오래된 데이터를 보관하면 Data Lake의 기록 보고에 사용할 수 있는 데이터를 유지하면서 Cosmos DB에 대한 비용을 줄일 수 있습니다.

패키지 서비스

패키지 서비스는 모든 패키지에 대한 정보를 저장합니다. 패키지에 대한 스토리지 요구 사항은 다음과 같습니다.

  • 장기 스토리지
  • 높은 쓰기 처리량이 필요한 대용량 패키지 처리 가능
  • 패키지 ID별 간단한 쿼리 지원 참조 무결성에 대한 복잡한 조인 또는 요구 사항 없음

패키지 데이터는 관계형이 아니기 때문에 문서 지향 데이터베이스가 적절하며 Azure Cosmos DB는 분할된 컬렉션을 사용하여 매우 높은 처리량을 얻을 수 있습니다. 패키지 서비스에서 작업하는 팀은 MEAN 스택(MongoDB, Express.js, AngularJS, Node.js)을 잘 알고 있으므로 Azure Cosmos DB에 대해 MongoDB API를 선택합니다. 이를 통해 관리형 Azure 서비스인 Azure Cosmos DB의 혜택을 누리는 동시에 기존의 MongoDB 사용 경험을 활용할 수 있습니다.

다음 단계

마이크로 서비스 아키텍처에서는 몇 가지 일반적인 문제를 완화하는 데 도움이 되는 디자인 패턴에 대해 알아봅니다.