BLOG

[실습예제] Amazon DynamoDB를 위한 확장 가능한 서버리스 가져오기 프로세스 생성하기
작성일: 2020-05-29

Amazon DynamoDB는 데이터에 대한 낮은 지연 시간 액세스를 제공하도록 설계된 웹 스케일 NoSQL 데이터베이스입니다. 주 데이터 저장소로서 서버리스 애플리케이션과 일반적인 엔터프라이즈 아키텍처에 적합합니다. 오늘 블로그 글에선 서버리스 접근 방식을 사용하여 DynamoDB로 대량의 데이터를 가져올 수 있는 방법을 보여드리겠습니다. 이를 통해 Amazon S3는 스테이징 영역으로, AWS Lambda를 사용자 지정 비즈니스 로직으로 사용합니다.

 

이 패턴은 데이터 변환 로직으로부터 스케일링 난제를 분리하기 때문에 DynamoDB로의 일반적인 가져오기 메커니즘으로 유용합니다. 수신 데이터는 JSON, CSV 또는 애플리케이션이 생성하는 모든 사용자 정의 형식으로 포맷된 S3 개체에 저장됩니다. 이 프로세스는 큰 파일을 몇 개만 가져오든 작은 파일을 많이 가져오든 상관없이 작동되며, 병렬화를 활용해 데이터를 DynamoDB 테이블로 빠르게 불러옵니다.

 

 

이는 업스트림 서비스가 트랜잭션 정보를 생성하는 애플리케이션에 유용하며 급증하는 워크로드에 의해 생성된 데이터를 처리하는 데 효과적일 수 있습니다. 또는 다른 데이터 소스에서 DynamoDB로 마이그레이션하는 간단한 방법이기도 하며, 특히 대규모 데이터셋의 경우 더욱 그러합니다.

 

본 게시물에는 두 가지의 다른 애플리케이션 가져오기 방법을 다룹니다. 첫 번째는 DynamoDB 테이블로 직접 가져오는 것이고, 두 번째는 가져오기 과정에서 볼륨을 평활화하기 위한 좀 더 심화된 방식입니다. 이 코드는 AWS SAM(Serverless Application Model)을 사용하므로 애플리케이션을 자신의 AWS 계정에 배포할 수 있습니다. 본 예제에서는 AWS Free Tier 에서 다루는 리소스를 생성하지만 대규모 데이터 가져오기에 비용이 발생할 수 있습니다.

 

두 예제 애플리케이션을 모두 설정하려면 GitHub 저장소를 방문하여 README.md 파일의 지침을 따릅니다.

 

 

S3에서 Dynamo로 직접 데이터를 가져오기

첫 번째 예제 애플리케이션은 람다 함수를 통해 S3에서 DynamoDB로 직접 데이터를 로드 합니다. 이 때 다음과 같은 아키텍처를 사용합니다.

 

  1. 다운스트림 프로세스는 JSON 형식의 소스 가져오기 데이터를 생성하고 S3 버킷에 기록합니다.
  2. 객체가 저장되면 S3는 주 람다 기능을 호출합니다.
  3. 함수는 S3 개체를 읽고 JSON을 DynamicoDB 테이블의 올바른 형식으로 변환합니다. 이는 데이터를 일괄적으로 테이블로 업로드합니다.

 

저장소의 SAM 템플릿온디맨드 용량(on-demand capacity)을 사용하도록 구성된 파티션 키로 DynamoDB 테이블을 생성합니다. 이 모드는 DynamicoDB 서비스가 가져오기 프로세스에 필요한 쓰기 수에 맞게 적절히 확장할 수 있게 합니다. 이는 표준 프로비저닝 모드에서처럼 DynamoDB 테이블 용량을 관리할 필요가 없음을 의미합니다.

 

DDBtable:

    Type: AWS::DynamoDB::Table

    Properties:

      AttributeDefinitions:

      – AttributeName: ID

        AttributeType: S

      KeySchema:

      – AttributeName: ID

        KeyType: HASH

      BillingMode: PAY_PER_REQUEST

 

아래의 템플릿은 데이터를 가져오는 람다 함수를 정의합니다.

 

ImportFunction:

    Type: AWS::Serverless::Function

    Properties:

      CodeUri: importFunction/

      Handler: app.handler

      Runtime: nodejs12.x

      MemorySize: 512

      Environment:

        Variables:

          DDBtable: !Ref DDBtable     

      Policies:

        – DynamoDBCrudPolicy:

            TableName: !Ref DDBtable       

        – S3ReadPolicy:

            BucketName: !Ref InputBucketName

      Events:

        FileUpload:

          Type: S3

          Properties:

            Bucket: !Ref InputS3Bucket

            Events: s3:ObjectCreated:*

            Filter:

              S3Key:

                Rules:

                  – Name: suffix

                    Value: ‘.json’

 

이는 SAM 정책 템플릿을 사용하여 DynamoDB 테이블에 대한 쓰기 액세스와 S3 버킷에 대한 읽기 액세스를 제공합니다. 또한 .json 접미사가 있는 새 객체에 대해서만 필터링하면서 S3에서 함수를 호출하는 이벤트를 정의합니다.

 

 

어플리케이션 테스트하기

  1. GitHub 저장소의md에 따라 첫 번째 애플리케이션을 배포하고 애플리케이션의 S3 버킷 이름과 DynamoDB 테이블 이름을 기록합니다.
  2. dataGenerator 디렉토리로 다음과 같이 변경합니다.

cd ./dataGenerator

  1. 테스트를 위한 샘플 데이터를 생성합니다. 다음 명령은 각각 100개의 레코드로 10개의 파일을 생성합니다.

node ./app.js 100 10

  1. 다음 버킷을 버킷 이름으로 대체하여 샘플 데이터를 애플리케이션의 S3 버킷에 업로드합니다.

aws s3 cp ./data/ s3://your-bucket –recursive

콘솔에는 샘플 데이터가 S3에 업로드되었음을 확인해주는 화면이 다음과 같이 표시됩니다.

  1. 몇 초 후 다음의 명령을 입력하여 애플리케이션의 DynamoDB 테이블에 있는 항목 수를 표시합니다. 여기서 테이블은 배포된 자신의 테이블 이름으로 바꿔주십시오.

aws dynamodb scan –table-name your-table –select “COUNT”

콘솔 출력 결과 1,000개의 항목이 DynamoDB에 저장되었으며 파일을 성공적으로

가져왔음을 알 수 있습니다.

 

온디맨드 프로비저닝에서는 40,000개의 per-table limit 쓰기 요청 단위 제한이 여전히 적용됩니다. 볼륨이 크거나 갑자기 스파이크가 발생하는 워크로드의 경우, DynamicoDB는 이 접근 방식을 사용할 때 가져오기를 조절할 수 있습니다. 모든 조절 이벤트는 DynamoDB service console 테이블의 메트릭 탭에 나타납니다. 제한은 인프라를 보호하기 위한 것이지만 이러한 많은 볼륨을 처리하려는 경우가 있습니다. repo의 두 번째 애플리케이션은 이 문제를 해결하는 방법을 보여줍니다.

 

온디맨드 프로비저닝을 사용할 경우 40,000개의 쓰기 요청 단위라는 테이블당 제한이 여전히 적용됩니다. DynamoDB는 볼륨이 크거나 갑자기 급증하는 워크로드의 경우 이 접근법을 사용할 때 가져오기를 제한할 수 있습니다. 조절 이벤트는 DynamoDB 서비스 콘솔에 있는 표의 메트릭 탭에 나타난다. 조절은 인프라를 보호하기 위한 것이지만 이러한 많은 볼륨을 처리하려는 경우가 있다. repo의 두 번째 신청서는 이것을 다루는 방법을 보여준다.

 

 

가져오기 프로세스의 극심한 부하 및 변동성 처리하기

이번 예제에서의 목표는 트래픽을 원활하게 처리하여 DynamoDB로의 부하 프로세스가 훨씬 더 일관되도록 하는 것입니다. 이를 달성하기 위해 사용되는 핵심 서비스는 Amazon SQS로, 로더 프로세스가 데이터를 DynamoDBDB에 저장할 때까지 모든 항목을 보유합니다. 이 경우의 아키텍처는 다음과 같습니다.

  1. 다운스트림 프로세스는 JSON 형식의 소스 가져오기 데이터를 생성하고 S3 버킷에 기록합니다.
  2. 개체가 저장되면 S3는 입력을 변환하는 람다 함수를 호출하여 Amazon SQS 대기열에 메시지로 추가합니다.
  3. 람다는 SQS 대기열을 폴링하고 메시지 배치를 처리하는 기능을 호출합니다.
  4. 함수는 JSON 메시지를 DynamicoDB 테이블의 올바른 형식으로 변환합니다. 이는 데이터를 일괄적으로 테이블로 업르도 해줍니다.

 

 

어플리케이션 테스트하기

이 테스트에서는 더 많은 수의 S3 개체를 사용하여 훨씬 더 많은 양의 데이터를 생성합니다. 아래 지침은 100,000개의 샘플 레코드를 생성하므로 이 코드를 실행하면 AWS 청구서에 비용이 발생할 수 있습니다.

  1. GitHub 저장소의md에 따라 두 번째 애플리케이션을 배포하고 애플리케이션의 S3 버킷 이름과 DynamoDB 테이블 이름을 기록합니다.
  2. dataGenerator 디렉토리로 다음과 같이 변경합니다.

cd ./dataGenerator

  1. 테스트를 위한 샘플 데이터를 생성합니다. 다음 명령은 각각 1,000개의 레코드로 100개의 파일을 생성합니다.

node ./app.js 1000 100

  1. 샘플 데이터를 애플리케이션의 S3 버킷에 업로드하여 아래 버킷을 배포된 버킷 이름으로 바꿉니다.

aws s3 cp ./data/ s3://your-bucket –recursive

이 프로세스는 저장소에서 기본 구성으로 완료하는 데 약 10분이 소요됩니다.

  1. DynamoDB 콘솔에서 애플리케이션의 테이블을 선택한 다음 메트릭 탭을 선택합니다. 차트를 확대하려면 쓰기 용량 그래프를 그래프를 선택합니다.

 

기본 구성은 그것이 어떻게 작동하는지 설명하기 위해 부하 프로세스를 의도적으로 느리게 합니다. 이 접근방식을 사용하면, 데이터베이스에 대한 로드는 분당 125-150개의 쓰기 용량 단위(WCU)를 소비하면서 훨씬 더 일관적입니다. 설계는 필요에 따라 DynamoDB 테이블로 얼마나 빨리 데이터를 로드하는지를 변경할 수 있게 해줍니다.

 

 

작동방법 알아보기

이 두 번째 애플리케이션에서는 애플리케이션이 구성 설정을 사용하여 데이터 흐름을 다음 단계로 조절하는 여러 지점이 있습니다.

 

  1. AddToQueue 함수: 이 함수는 소스 S3 객체로부터 25개의 메시지 배치로 데이터를 SQS로 로드합니다. 소스 레코드의 크기에 따라 크기 제한이 256Kb인 단일 SQS 메시지에 레코드를 추가할 수 있습니다. 이 메시지를 gzip으로 압축하여 더 많은 레코드를 추가할 수도 있습니다.
  2. 함수 동시성: SAM 템플릿은 ReservedConcurrentExecutions 속성을 사용하여 로더 함수의 concurrency(동시성)를 1로 설정합니다. 사실상 이것은 람다가 이 기능을 확장하지 못하게 하는데, 이는 처리가 끝나는 즉시 SQS에서 다음 배치를 계속 가져오는 것을 의미합니다. 동시성은 이 값이 증가함에 따라 SQS에 사용 가능한 메시지가 있는 경우 DynamoDB 테이블로의 로딩이 비례적으로 증가합니다. 로드 프로세스에서 병렬화를 사용하려면 1보다 큰 값을 선택하십시오.
  3. Loader 함수: 이것은 SQS 대기열의 메시지를 소비합니다. SAM 템플릿에 구성된 BatchSize는 호출당 4개의 메시지로 설정됩니다. 각 메시지에는 25개의 레코드가 포함되기 때문에 대기열에 충분한 메시지가 있을 때 호출당 100개의 레코드를 나타냅니다. BatchSize 값을 1에서 10으로 설정할 수 있으므로 애플리케이션의 기본값에서 이 값을 늘릴 수 있습니다

 

 

이러한 설정을 결합하면 DynamoDB로 데이터를 로드하는 처리량을 크게 늘릴 수 있습니다. 부하를 증가시키면 소비되는 WCU도 증가하여 비용이 증가합니다. 사용자의 사용 사례는 속도와 비용 사이의 최적의 균형에 대해 알려줄 수 있고 변경할 수 있습니다. 요구사항에 맞게 조정하는 작업은 간단합니다.

 

또한 사용되는 각 서비스에는 자체적인 서비스 한도가 있습니다. 높은 생산 부하에 대해서는 설정된 할당량, 그리고 이러한 할당량들이 소프트 한계인지 하드 한계인지를 이해하는 것이 중요합니다. 애플리케이션에 더 높은 처리량이 필요한 경우 AWS 지원 센터 티켓을 통해 소프트 한도 인상을 요청할 수 있습니다.

 

 

 

글을 마치며…

DynamoDB는 네이티브 가져오기 프로세스를 제공하지 않으며 기존 솔루션이 계획되지 않은 대규모 가져오기 요구를 충족하지 못할 수 있습니다. AWS Database Migration Service는 서버가 없는 것이 아니며 AWS Data Pipeline은 이벤트 기반보다는 스케줄 기반입니다. 이 솔루션은 S3 온디맨드 방식으로 들어오는 데이터에 응답하는 완전한 서버 없는 대안을 제공하도록 설계되었습니다.

 

오늘은 S3 버킷에 삽입된 물체에 의해 트리거된 DynamoDB 테이블로 직접 간단한 가져오기 프로세스를 생성하는 방법을 보여드렸습니다. 이는 거의 실시간에 가까운 가져오기 과정을 제공합니다. 또한 대량의 작업량이나 급증하는 작업 부하에 대한 트래픽을 원활히 처리할 수 있는 보다 진보된 접근 방식입니다. 따라서 DynamoDB를 위한 복원적이고 일관된 데이터 가져오기를 만드는 데 도움이 됩니다.

 

더욱 자세한 내용을 원하시면 아래의 영상을 통해 DynamoDB 임포터 애플리케이션을 배포하고 테스트하는 방법을 확인해 주시기 바랍니다.

 

원문URL :  https://aws.amazon.com/ko/blogs/compute/creating-a-scalable-serverless-import-process-for-amazon-dynamodb/

** 메가존 클라우드 TechBlog는 AWS BLOG 영문 게재 글 중에서 한국 사용자들에게 유용한 정보 및 콘텐츠를 우선적으로 번역하여 내부 엔지니어 검수를 받아서, 정기적으로 게재하고 있습니다. 추가로 번역 및 게재를 희망하는 글에 대해서 관리자에게 메일 또는 SNS 페이지에 댓글을 남겨주시면, 우선적으로 번역해서 전달해드리도록 하겠습니다.