AWS 기술 블로그

AWS 서비스를 사용하는 멀티테넌트 SaaS 환경에서의 데이터 수집

본 게시물은 AWS Partner Network(APN) Blog에 게시된 Data Ingestion in a Multi-Tenant SaaS Environment Using AWS Services” by Peter Yang and Ranjith Raman을 한국어로 번역한 글입니다.

Amazon Web Services (AWS) 의 서비스를 사용하여 데이터 수집 아키텍처를 설계하고 구현하는 방법에는 여러 가지가 있습니다. 멀티테넌트 SaaS (Software-as-a-Service) 환경에서 데이터를 수집할 때는 솔루션에 추가적으로 고려해야할 사항, 과제 및 절충 사항이 있습니다.

SaaS에서는 테넌트 세부 정보가 수집 프로세스 전반에 걸쳐 캡처되고 전파되어 테넌트에 따라 데이터를 격리하고 워크로드와 스토리지를 분할하는 데 있어서 직접적인 역할을 하도록 해야합니다.

멀티테넌트 데이터 수집 프로세스를 구현할 때는 여러 가지 전략을 사용할 수 있습니다. 일부는 전용 (사일로) 메커니즘을 사용하고 다른 일부는 공유 (풀링) 수집 모델을 사용할 수 있습니다. 두 방법 모두 유효하며 혼용될 수 있지만, 이 게시물에서는 풀링 모델에서 데이터 수집을 구현하는 데에 초점을 맞추고, 테넌트가 수집 리소스를 공유할 때 발생하는 다양한 고려 사항을 강조할 것 입니다.

이 게시물에는 코드가 포함된 실제 예제 솔루션이 포함되어 있으며 이 솔루션을 배포하는 단계는 GitHub를 통해 확인할 수 있습니다.

멀티테넌트 SaaS 환경에서의 데이터 통합을 위한 설계 고려 사항

솔루션의 기술 아키텍처를 자세히 살펴보기 전에, 먼저 멀티테넌트 데이터 수집 프로세스를 설계할 때 고려해야 할 몇 가지 주요 고려 사항부터 살펴보겠습니다. 다음은 SaaS 제공업체가 이러한 솔루션을 구축할 때 고려하는 공통 요소들입니다.

  • 확장성 및 성능: 대량의 요청을 처리하고 수천 개의 테넌트로 원활하게 확장할 수 있습니다.
  • 보안 및 격리: 테넌트 이벤트가 인증되도록 제어를 구현하고 이러한 제어를 사용하여 데이터 파티셔닝 및 격리 결정을 내립니다.
  • 리소스 관리: 원활한 용량 관리를 통해 예측하기 어려운 급격한 트래픽을 원활하게 처리합니다.
  • 운영 효율성: 운영 및 관리 오버헤드를 감소합니다.

솔루션 아키텍처

이 게시물에서는 데이터를 수집 및 집계하는 샘플 솔루션 (예: 전자 상거래 웹 사이트 및 POS 애플리케이션) 을 참조합니다. 이 솔루션에서 이 데이터는 테넌트/고객별 속성과 함께 처리 (보강 및 변환) 되고 백엔드 데이터 스토어에 저장됩니다.

이러한 애플리케이션은 일반적으로 추세를 파악하고 데이터에서 영향력 있는 통찰력을 도출하기 위해 ‘총 주문수‘ 또는 ‘구매한 제품 카테고리‘와 같은 클릭스트림 데이터 및/또는 이벤트를 추적합니다. 특정 순간의 활성 사용자 수에 따라 1초마다 대량의 데이터가 생성될 수 있습니다.

비즈니스와 이와 같은 사용 사례를 지원하려면 확장성과 성능이 뛰어나고 지연 시간이 매우 짧으면서 이러한 이벤트를 처리할 수 있는 아키텍처가 필요합니다. 다음 다이어그램은 당사 솔루션의 아키텍처를 보여줍니다.

그림 1 — High-level 아키텍처

요청 흐름

이 아키텍처의 세부 사항을 자세히 살펴보기 전에 이 샘플 솔루션에 사용되는 상위 수준 요소를 살펴보겠습니다. 아래에서 솔루션의 일부인 여러 단계를 확인할 수 있습니다.

  1. 이 솔루션의 흐름은 테넌트가 Amazon API Gateway에서 제공하는 REST API를 사용하여 SaaS 환경으로 메시지 또는 이벤트를 보내는 다이어그램의 (그림 1) 왼쪽에서부터 시작됩니다. 이는 스트리밍 이벤트의 진입점이며 개별 테넌트 이벤트 인증을 담당합니다.
  2. Amazon API Gateway는 Lambda Authorizer를 사용하여 Amazon Cognito로 JSON Web Token(JWT)의 유효성을 검증합니다. Lambda Authorizer는 tenantId를 Amazon API Gateway의 컨텍스트에 추가하여 이를 Amazon Kinesis Data Stream에 대한 입력으로 사용할 수 있도록 합니다.
  3. Amazon API Gateway는 프록시 역할을 하여 Kinesis Data Streams로 테넌트 이벤트를 푸시합니다. Kinesis Data Streams는 어떤 규모에서든 데이터 스트림을 쉽게 캡처, 처리 및 저장할 수 있는 서버리스 스트리밍 데이터 서비스입니다. 이 예시에서 Kinesis Data Streams는 다양한 테넌트로부터 스트리밍 데이터를 수집하는 데이터 수집 스트림입니다.
  4. Kinesis Data Streams는 데이터를 Amazon Managed Service for Apache Flink로 푸시합니다. Amazon Managed Service for Apache Flink는 데이터를 처리하고 tenantIdtimestamp 로 데이터를 보강하는데 이 데이터는 Amazon Kinesis Data FirehoseAmazon Simple Storage Service(Amazon S3) 의 접두사를 생성하는 데 사용됩니다.
  5. Amazon Managed Service for Apache Flink는 테넌트 이벤트를 Kinesis Data Firehose로 푸시합니다. Kinesis Data Firehose는 데이터를 저장하고 추가 처리를 하기 위해 S3로 실시간 스트리밍 데이터를 직접 전송합니다. S3는 멀티테넌트 데이터를 효율적으로 저장하고 구성하기 위한 여러 메커니즘을 제공합니다. 이에 대해 더 자세히 알아보려면 S3를 사용할 때 멀티 테넌시를 구현하기 위한 다양한 전략에 대해 설명하는 이 AWS 블로그 게시물을 확인하십시오.

이제 상위 수준 아키텍처를 이해했으니 솔루션의 각 구성 요소를 더 자세히 살펴보겠습니다.

인증 및 권한 부여 요청

Amazon API Gateway는 이 솔루션의 진입점으로, 테넌트 애플리케이션에서 데이터 스트림을 수집하는 확장 가능한 방법을 제공하는 안전한 진입점 역할을 합니다. 또한 API Gateway는 테넌트 컨텍스트를 추출하고 들어오는 요청을 승인하기 위해 Lambda Authorizer를 사용합니다.

이 테넌트 정보는 Amazon Cognito에서 테넌트를 인증할 때 생성된 인코딩된 JWT을 통해 전달됩니다. 이 컨텍스트는 이 솔루션이 수집된 데이터를 개별 테넌트와 연결할 수 있도록 하는 데 필수적입니다.

API Gateway에서 처리된 각 요청은 Lambda Authorizer를 호출합니다. Lambda Authorizer는 JWT에서 테넌트 컨텍스트를 추출하고 요청 액세스 범위를 지정하는 AWS ID 및 액세스 관리 (IAM) 정책을 반환합니다.

정책과 함께 요청의 컨텍스트에 테넌트 식별자 (tenantId) 도 추가합니다. 흐름의 후반부에서 이 컨텍스트 값을 어떻게 사용하는지 살펴보겠습니다. 다음은 tenantId 를 컨텍스트의 일부로 설정하는 방법을 보여주는 예제 코드입니다.

policy = AuthPolicy(principalId, awsAccountId)
policy.restApiId = apiGatewayArnTmp[0]
policy.region = tmp[3]
policy.stage = apiGatewayArnTmp[1]
policy.allowAllMethods()
authResponse = policy.build()
context = {
    'tenantId': tenantId,
}
authResponse['context'] = contextreturn authResponse

Kinesis Data Streams로 데이터 라우팅

요청이 성공적으로 처리되면 Amazon API Gateway가 Amazon Kinesis Data Streams로 메시지를 전달하도록 구성할 수 있습니다. Amazon Kinesis Data Streams는 테넌트 데이터 스트림을 수집하고 처리합니다. 아래 그림 2는구성 단계를 보여줍니다.

여기서는 AWS 서비스로의 통합 요청의 유형을 설정합니다. 즉, 요청을 AWS 서비스 (이 예에서는 Kinesis Data Streams) 로 전달한다는 의미입니다.

그림 2 — Amazon API Gateway 통합 요청 값

요청이 스트림으로 전달되기 전에 API Gateway에서 변환을 적용하여 요청을 Kinesis Data Streams에서 예상하는 형식으로 변환합니다.

Amazon API Gateway를 사용하면 매핑 템플릿을 사용하여 메서드 요청의 페이로드를 해당하는 통합 요청으로 매핑할 수 있습니다. 이 솔루션에서는 그림 3과 같이 템플릿을 사용하여 StreamName, DataPartitionKey의 값을 설정합니다. PartitionKey 값은 Kinesis Data Streams의 필수 속성인데 우리는 이 PartitionKey 값으로 Lambda Authorizer가 설정한 컨텍스트의 일부인 tenantId 필드를 사용합니다.

이 템플릿을 통해 다운스트림 서비스로 전달되는 모든 요청이 요청을 보내는 테넌트와 연결되도록 합니다.

그림 3 — Amazon API Gateway 매핑 템플릿

Amazon Managed Service for Apache Flink을 사용하여 스트리밍 데이터를 처리

이전 섹션에서 설명한 것처럼 데이터 스트림으로 보내는 모든 메시지에는 tenantId 라는 파티션 키가 있습니다. 이 파티션 키 값은 메시지를 처리할 샤드에 영향을 줍니다.

각 Kinesis 스트림에는 하나 이상의 샤드가 있으며, 샤드 수는 Kinesis가 처리할 수 있는 데이터의 양에 직접적인 영향을 미칩니다. 파티션 키로 인해 핫 샤드가 생성되어 스트림 성능에 영향을 미칠 수 있다는 점을 염두에 두어야 합니다.

데이터 스트림에서 메시지를 처리한 후에는 Amazon Managed Service for Apache Flink를 사용하여 데이터를 추가로 분석합니다. 이 서비스를 사용해서 우리는 Java와 같은 프로그래밍 언어를 사용하여 스트리밍 데이터를 처리하고 분석할 수 있습니다.

저희 솔루션에서는 Flink 작업을 사용해서 데이터를 다음 서비스로 전달하기 전에 메시지에 필드를 추가해서 보강합니다.

그림 4 의 구현에서 볼 수 있듯이 Flink 작업에는 데이터의 출처를 나타내는 InputStreamName이 있으며, 이 경우에는 Kinesis Data Stream 입니다. 위에서 언급했듯이 Flink 작업은 메시지를 Kinesis Data Firehose의 전송 스트림으로 푸시하기 전에 tenantId 에 대한 추가 속성과 타임스탬프 필드를 추가합니다.

그림 4 — Amazon Managed Service for Apache Flink — 입력 Kinesis Data Streams와 Kinesis Data Firehose 출력을 설정합니다.

또한 아래 그림 5의 코드에서 볼 수 있듯이 tenantId 필드는 메시지가 Amazon S3에 도착할 경로를 나타내는 데 사용되며 타임스탬프는 Flink 작업이 메시지를 처리한 정확한 시간을 반영합니다.

그림 5 — Flink Job의 테넌트 ID 설정

Amazon Kinesis Data Firehose를 사용한 데이터 전송

이 솔루션에서 우리는 Amazon Kinesis Data Firehose를 사용하여 S3에 메시지를 전송합니다. 특히 SaaS 시스템에서 테넌트가 많은 경우 확장성을 높이기 위해 테넌트별 접두사 분할 모델을 사용하는 게 좋습니다.

Flink를 사용하면 Flink 작업에서 S3로 메시지를 직접 전송할 수 있습니다. 이 외에도 Kinesis Data Firehose로 데이터를 전송하면, 향후 이 솔루션을 유연하게 확장하여 데이터를 Amazon RedshiftAmazon OpenSearch Service및 기타 모니터링 솔루션과 같은 다른 대상으로 보낼 수 있습니다.

그림 6 — Amazon Kinesis Data Firehose 전송 스트림

그림 6에서 볼 수 있듯이 Kinesis Data 전송 스트림인 delivery-multi-tenant-firehose-stream은 동적 파티셔닝 기능을 활용합니다. 이를 통해 데이터 내의 키를 사용하여 Kinesis Data Firehose에서 스트리밍 데이터를 파티셔닝할 수 있습니다.

그림 7 – TenantID 및 Timestamp를 사용한 동적 파티셔닝

키는 해당 테넌트의 S3 접두사 위치로 전송되기 전에 데이터를 그룹화하는 데 도움이 됩니다. 그림 7에서 볼 수 있듯이 수신 메시지의 일부인 tenantId 및 timestamp 필드를 사용하여 동적 파티셔닝을 구현했습니다. tenantId를 S3 접두사의 일부로 사용함으로써 우리는 데이터를 사용할 때 S3에 대한 테넌트 격리 전략의 일부로 사용할 수 있는 IAM 정책을 만들 수 있었습니다.

마지막으로, S3로 데이터를 전송할 때 Amazon Kinesis Data Firehose는 전송 스트림의 버퍼링 구성을 기반으로 여러 수신 레코드를 연결합니다. S3로의 데이터 전송 빈도는 전송 스트림에 구성한 S3 버퍼 크기 및 버퍼 간격 값에 따라 결정됩니다. 이에 대한 자세한 내용은 AWS 설명서에서 확인할 수 있습니다.

결론

이 게시물에서는 AWS 서비스를 사용하여 멀티테넌트 환경에서 데이터 수집 및 처리 엔진을 구축하는 방법을 살펴보았고, 이 데이터 파이프라인의 각 구성 요소와 SaaS 멀티테넌트 데이터 수집 프로세스를 설계하는 방식에 영향을 미칠 수 있는 몇 가지 주요 고려 사항을 함께 살펴보았습니다.

또한 데이터의 안전한 처리를 보장하는 파이프라인 구성 요소가 내장되어 있는지 확인하면서 AWS 서비스를 사용하여 멀티테넌트 스트리밍 데이터를 수집, 변환 및 저장하는 방법도 살펴보았습니다.

여기에 제시된 샘플 애플리케이션을 활용하면 AWS에서 완벽하게 작동하는 솔루션을 구축하는 전반적인 경험을 더 잘 이해할 수 있고. 이를 통해 SaaS 데이터 수집 프로세스의 요구 사항에 부합하는 정책을 중심으로 구성하는 좋은 출발점으로 활용 할 수 있습니다.

이 솔루션을 더 자세히 살펴보려면 환경의 모든 이동 요소를 이해하는 데 도움이 되는 단계별 배포 지침을 찾을 수 있는 GitHub 리포지토리를 살펴보시기 바랍니다.

AWS SaaS 팩토리에 대한 정보

AWS SaaS Factory는 SaaS 여정의 모든 단계에서 조직을 지원합니다. 새로운 제품을 구축하든, 기존 애플리케이션을 마이그레이션하든, AWS에서 SaaS 솔루션을 최적화하든 관계없이 저희가 도와드릴 수 있습니다. AWS SaaS Factory Insights Hub를 방문하여 더 많은 기술 및 비즈니스 콘텐츠와 모범 사례를 찾아보십시오.

SaaS 빌더는 계정 담당자에게 연락하여 참여 모델에 대해 문의하고 AWS SaaS Factory 팀과 협력하는 것이 좋습니다.

등록하여 AWS의 최신 SaaS 뉴스, 리소스 및 이벤트에 대한 최신 정보를 받아보십시오.

Beomjun Kim

Beomjun Kim

김범준 Solutions Architect는 ISV/DNB 고객들이 AWS 서비스를 활용해 SaaS 서비스를 만들고 고도화하는 과정에서 기술적인 도움을 드리는 업무를 하고 있습니다.

Hyeryeong Joo

Hyeryeong Joo

주혜령 솔루션즈 아키텍트는 대규모 엔터프라이즈 시스템 개발과 운영 경험을 바탕으로, 현재는 ISV/DNB 고객들께서 AWS 서비스를 잘 활용하실 수 있도록 기술적인 도움을 드리는 업무를 하고 있습니다.