Amazon Web Services 한국 블로그

AWS Config 업데이트 – S3 버킷 보안을 위한 두 가지 관리 규칙 추가

AWS Config는 AWS  자원 상태와 그 사이 관계를 계속 모니터링 하는 서비스입니다. 각 서비스 자원을 선택한 다음, 자원에 영향을 주는 구성 변경 타임 라인을 볼 수 있습니다 (자세한 내용은 AWS Config와 AWS 자원 관계 추적을 참조하십시오).

AWS Config rules은 AWS Config의 “관리형” 컬렉션과 사용자가 직접 작성한 사용자 정의 규칙을 지원하는 강력한 규칙 시스템으로 확장합니다 (AWS Config Rules – 클라우드 리소스에 대한 동적 컴플라이언스 검사 등 참조). ). Config Rules (AWS Lambda 함수)은 AWS 자원의 이상적인 상태를 나타냅니다. 함수는 구성 변경이 감지 될 때, 호출되며 표준 규정 준수 여부를 확인합니다.

약 30 개의 관리 규칙에 접근할 수 있으며, 예를 들어 EC2 인스턴스 및 관련 리소스를 확인하는 몇 가지 규칙은 다음과 같습니다.

두 가지 신규 규칙
오늘은 S3 버킷 보안을 유지하는 데 도움이되는 두 개의 새로운 관리 규칙을 추가하고 있습니다. 클릭 한 번으로 이러한 규칙을 활성화 할 수 있습니다. 새로운 규칙은 다음과 같습니다.

s3-bucket-public-write-prohibited – 전역 쓰기 접근을 허용하는 버킷을 자동으로 식별합니다. 이 구성을 의도적으로 만들지 않는 이유는 권한이 없는 사용자가 악성 콘텐트를 버킷에 추가하고 기존 콘텐트를 삭제 (덮어 쓰기) 할 수 있습니다.  이 규칙은 계정의 모든 버킷을 검사합니다.

s3-bucket-public-read-prohibited – 전역 읽기 접근 허용하는 버킷을 자동으로 식별합니다. 그러면, 웹 사이트 및 문서를 포함하여 공개적으로 사용할 수 있는 콘텐츠의 플래그가 지정됩니다. 이 규칙은 계정의 모든 버킷을 검사합니다.

기존 규칙과 마찬가지로 새 규칙은 일정에 따라 또는 Config가 감지 한 변경 사항에 따라 실행될 수 있습니다. 모든 규칙의 준수 상태를 한 눈에 볼 수 있습니다.

각 규정 준수 평가는 밀리 세컨드 단위로 실행됩니다. 100 개의 버킷으로 계정을 검색하는 데 1 분도 안 걸립니다. 대부분의 경우, NP 완료 문제를 다항식 시간에 처리 할 수 있는 최첨단 제약 해결 기법을 사용하는 추론 엔진에 의해 규칙이 평가됩니다 (NP 대 P 문제 참조). 이 작업은 AWS 내부의 개발 부분 중 하나로서 아래의 re:Invent  Automated Formal Reasoning About AWS Systems 발표 자료를 참고하시기 바랍니다.

정식 출시
새로운 규칙은 현재 사용할 수 있으며 오늘부터 사용할 수 있습니다. 다른 규칙과 마찬가지로 한 달에 규칙 당 2 달러로 책정됩니다.

Jeff;

이 글은 AWS Config Update – New Managed Rules to Secure S3 Buckets의 한국어 번역입니다.

AWS Glue 정식 출시 – 완전 관리형 ETL 서비스

오늘 AWS Glue 서비스가 정식 출시되었습니다. AWS Glue는 완전 관리형, 서버리스 기반 클라우드 데이터 추출, 변환 및 로드 (ETL) 서비스입니다. 이 서비스는 몇 가지 매우 중요한 방식으로 다른 ETL 서비스 및 소프트웨어 플랫폼과 다릅니다.

첫째, Glue는 “서버가 필요하지 않습니다.” 어떤 인프라 자원도 프로비저닝하거나 관리 할 필요가 없으며, Glue 실행될 때만 비용을 지불합니다. 둘째, Glue는 많은 데이터 소스, 데이터 유형 및 다양한 유형의 파티션에서 스키마를 자동으로 감지하고 추론 할 수 있는 크롤러를 제공합니다. 편집, 버전 관리, 질의 및 분석을 위해 이러한 생성 된 스키마를 중앙 데이터 카탈로그에 저장합니다. 셋째, Glue는 자동으로 ETL 스크립트 (Python 기반)를 생성하여 원본 형식의 데이터를 대상 형식으로 변환합니다. 마지막으로, Glue를 사용하면 개발자가 자신이 선호하는 도구를 사용하여 ETL 스크립트로 엔드 포인트를 만들 수 있습니다. 자, 실제 예제를 살펴 보도록 합시다.

Crawlers

먼저 Amazon S3의 항공편 데이터에 대한 크롤러를 만들어야 합니다.  Glue 콘솔에서 Crawlers를 선택하고 거기에서 온 스크린 프롬프트를 따릅니다. 첫 번째 데이터 소스로 s3://crawler-public-us-east-1/flight/2016/csv/를 지정할 것입니다 (필요할 경우 나중에 추가 할 수 있습니다). 다음으로 flight라고 하는 데이터베이스를 만들고 테이블에 항공편의 접두어도 지정합니다.

크롤러는 데이터 세트를 거쳐 다양한 폴더(이 경우에는 일년 데이터)를 통해 파티션과 스키마를 감지하며 테이블을 만듭니다. 추가 데이터 소스와 작업을 크롤러에 추가하거나 데이터를 동일한 데이터베이스로 푸시하는 별도의 크롤러를 만들 수 있지만 자동 생성 된 스키마를 살펴 보겠습니다.

BIGINT에서 INT로 이동하여 일년으로 빠르게 스키마를 변경하려고 합니다. 필요한 경우 스키마의 두 버전을 비교할 수 있습니다.

이제 데이터를 올바르게 구문 분석하는 방법을 알게 되었으므로, 필요한 변경을 할 수도 있습니다.

ETL Jobs
이제 작업 하위 콘솔로 이동하여 Add Job를 클릭합니다.  이름을 설정하고, 데이터 소스를 선택한 후, 임시 파일을위한 S3 위치를 묻는 메시지를 따릅니다. 다음으로 “Create tables in your data target”를 지정하여 타겟을 추가하고, Parquet format으로 S3 위치를 목표로 지정합니다.

다음을 클릭하면 Glue가 제안한 다양한 매핑을 보여주는 화면이 나타납니다. 이제는 필요에 따라 수동으로 열을 조정할 수 있습니다.이 경우에는 X 버튼을 사용하여 필요 없는 열 몇 개를 제거합니다.

이를 통해 개발자에게 유용한 부분으로 넘어갈 수 있습니다.


Glue는 PySpark 스크립트를 생성하여 지금까지 제공 한 정보를 기반으로 데이터를 변환합니다. 왼쪽에는 ETL 작업의 흐름을 보여주는 다이어그램이 있습니다. 오른쪽 상단에는 주석이 달린 데이터 소스와 대상 등 기타 기능을 추가하는 데 사용할 수 있는 몇 가지 버튼이 있습니다. 이것은 transform을 클릭하면 얻을 수 있는 인터페이스입니다.

데이터 변환 또는 추가 데이터 소스를 추가하면, Glue가 왼쪽에 있는 다이어그램을 업데이트하여 데이터 흐름을 효과적으로 시각화 합니다. 또한, 원하는 코드를 콘솔에 작성하여 실행할 수도 있습니다. 현재 작업에 다른 작업, 일정 또는 작업 완료시 트리거를 추가 할 수 있습니다. 이를 통해, 더 많은 항공편 데이터를 추가 할 수 있어 동일한 데이터를 S3 형식으로 다시 읽어올 수 있습니다.

여기서 ETL 작업을 코드로 저장하는 방식의 장점을 잠깐 살펴 봅니다. 프로그램 코드는 쉽게 변경 혹은 테스트 가능하며 버전을 통해 다양한 사람이 공유할 수 있습니다. 개발자들은 매일 코드를 작성하기 때문에, 손쉽게 데이터 처리를 위한 코드를 만들어 효율적으로 활용 가능합니다.

개발용 엔드 포인트 및 노트북(Notebooks)

개발용 엔드포인트는 Glue 스크립트를 개발하고 테스트하는 데 사용되는 환경입니다. Glue 콘솔에서 “Dev endpoints”로 이동하면 오른쪽 상단의 “Add endpoint”를 클릭하여 시작할 수 있습니다. 그런 다음 자체를 참조하는 보안 그룹 인 VPC를 선택하고 제공 준비가 완료 될 때까지 기다립니다.


일단 프로비저닝이 완료 되면 조치로 가서 노트북 서버 생성을 클릭하여 Apache Zeppelin 노트북 서버를 생성 할 수 있습니다.  인스턴스에 IAM 역할을 부여하고 데이터 소스와의 대화 권한이 있는지 확인합니다. 그런 다음 서버에 SSH를 연결하거나 노트북에 연결하여 스크립트를 대화식으로 개발할 수 있습니다.

비용 및 개발 문서
자세한 가격 정보는 여기에서 확인할 수 있습니다. 크롤러, ETL 작업 및 개발 엔드 포인트는 모두 DPU (Data Processing Unit Hours, 분 단위)에 청구됩니다. 각 DPU-Hour의 비용은 미국 버지니아 리전 기준 0.44 달러 입니다. 단일 DPU는 4vCPU 및 16GB의 메모리를 제공합니다.

이 글에서는 AWS  Glue가 가지고 있는 기능의 절반 만 다루었습니다.  더 자세한 사항은 기술 문서서비스 FAQ를  참고해 주시기 바랍니다. Glue에는 콘솔에서 수행 할 수 있는 모든 작업을 수행 할 수 있는 풍부하고 강력한 API가 있습니다.

또한, 오늘 두 개의 새로운 프로젝트를 발표합니다. aws-glue-libs 는 Glue와 대화하기 위한 유틸리티 세트를 제공합니다. aws-glue-samples repo에는 일련의 예제 작업이 포함되어 있습니다.

– Randall;

이 글은 Launch – AWS Glue Now Generally Available의 한국어 번역입니다.

AWS Migration Hub – 대기업을 위한 신규 클라우드 마이그레이션 기획 및 추적 서비스

일주일에 한 번, 시애틀 기업 임원 지원 센터 (Seattle Executive Briefing Center)에서 AWS 고객과 이야기를 하는데, 기업 혁신 프로세스를 이야기하면서 애플리케이션 마이그레이션에 대해 논의하기도합니다. 기업이 애플리케이션 포트폴리오를 클라우드로 이전하려고 할 때, 좀 더 구조화되고 정확한 과정을 통해 수행하려고합니다. 이러한 포트폴리오에는 대체적으로 수백 가지의 복잡한 Windows 및 Linux 응용 프로그램, 관계형 데이터베이스 등으로 구성됩니다. 고객은 클라우드로 이전을 빠르게 하고 싶지만 불확실한 것들이 많다는 점을 발견하였고, 일반적으로 다음과 같은 세 가지 주요 범주에 해당하는 문제를 발견했습니다.

  • 애플리케이션 발견 – 애플리케이션을 구동하는 모든 움직이는 부분을 깊이 있고 완벽하게 이해해야 합니다.
  • 서버 및 데이터베이스 마이그레이션 – 사내 구축 환경의 작업 부하 및 데이터베이스 테이블을 클라우드로 이전해야 합니다.
  • 추적 / 관리 – 대규모 애플리케이션 포트폴리오에 대한 이전을 동시에 진행되는 경우 애플리케이션 중심 방식으로 진행 상황을 추적하고 관리해야 합니다.

지난 2 년 동안 처음 두 가지 문제를 해결하는 일련의 도구를 출시했습니다. AWS Application Discovery Service는 시스템 정보 검색 및 수집 프로세스를 자동화하고, AWS Server Migration Service는 클라우드로 이동하는 작업 부하를 처리하며 AWS Database Migration Service는 최소한의 중단 시간으로 관계형 데이터베이스, NoSQL 데이터베이스 및 데이터웨어 하우스를 이동합니다. RacemiCloudEndure와 같은 파트너도 자체 마이그레이션 도구를 제공합니다.

신규 AWS Migration Hub
오늘 새로 공개하는 AWS Migration Hub에서는 AWS 및 파트너 마이그레이션 도구 모음을 함께 제공합니다. 본 서비스는 위에서 언급한 도구에 대한 접근을 제공하고, 마이그레이션 프로세스를 안내하며, MAP (Migration Acceleration Program)에 설명 된 방법 및 이전 과정에 대한 추적 기능을 지원합니다.

다음은 기본 화면입니다. 마이그레이션 프로세스 (검색, 마이그레이션 및 추적)에 대해 간략히 설명합니다.

Start discovery을 클릭하면 마이그레이션 프로세스의 흐름이 표시됩니다.

발견 단계를 건너 뛰고 즉시 마이그레이션을 시작할 수도 있습니다.

서버 목록은 AWS 마이그레이션 서비스 (Server Migration Service 또는 Database Migration Service), 파트너 도구 또는 AWS Application Discovery Service에서 수집 한 데이터를 사용하여 채워집니다.

Group as application으로 첫번째 애플리케이션을 만들 수 있습니다.

이전할 일부 애플리케이션을 식별하면, 허브의 Migrations 섹션에서 해당 애플리케이션을 추적 할 수 있습니다.

승인된 경우, 마이그레이션 도구는 상태 업데이트 및 결과를 Migration Hub으로 자동 전송하여 마이그레이션 상태 페이지에 표시합니다. 여기에서 Racemi DynaCenterCloudEndure Migration이 마이그레이션에서 중요한 역할을 담당하고 있음을 알 수 있습니다.

Migration Hub Dashboard를 확인하여 마이그레이션 상태를 추적 할 수 있습니다.

Migration Hub는 AWS 및 마이그레이션 파트너의 마이그레이션 도구와 함께 작동합니다. 자세한 내용은 통합 파트너 도구 목록을 참조하십시오.

정식 출시
AWS Migration Hub는 마이그레이션 도구를 사용할 수 있는 모든 AWS 리전에서 이전 작업을 관리 할 수 ​​있습니다. 다만, 허브 서비스 자체는 미국 서부 (오레곤) 지역에서 운영됩니다. 허브 서비스 사용에는 요금이 부과되지 않습니다. 마이그레이션 과정에서 사용하는 AWS 서비스에 대해서만 비용을 지불하게 됩니다.

클라우드 마이그레이션을 시작할 준비가 되어 있고 도움이 필요한 경우, 마이그레이션 파트너가 제공하는 서비스를 활용하시길 권장해 드립니다.

Jeff;

이 글은 AWS Migration Hub – Plan & Track Enterprise Application Migration의 한국어 번역입니다.

AWS SAM Local (베타) – 로컬 기반 서버리스 앱 테스트 및 개발 도구

오늘 신규 서버리스(Serverless) 개발 도구 인 SAM Local 베타 버전을 발표했습니다.이 도구를  통해 로컬에서 쉽게 작성하고 테스트 할 수 있습니다. 이 글에서는 SAM local을 사용하여, 개발자들이 코드 개발 시, 탭 혹은 스페이스 선호도 투표 할 수 있는 빠른  애플리케이션을 빌드, 디버그 및 배포하는 예제를 소개해 드리고자 합니다. AWS는 작년에 Serverless Application Model (SAM)을 소개하고, 이를 통해 서버리스 애플리케이션을 쉽게 배포 할 수 있습니다.  SAM은 AWS CloudFormation을 기반으로 하는 강력한 오픈 소스 기반 인프라 코드 구현 모델 입니다. 로 유지하기가 쉽고 가장 멋진 마스코트를 갖추고 있습니다.

SAM Local은 SAM의 아래와 같은 장점을 로컬 시스템으로 가져와서 사용 가능합니다.

SAM Local을 설치하는 데에는 몇 가지 방법이 있지만 가장 쉬운 방법은 NPM을 사용하는 것입니다. npm install -g aws-sam-local 명령을 사용하거나, 최신 버전을 원하면 github.com/awslabs/aws-sam-local (aws-sam-local  바이너리)에서 설치 가능합니다..

개발자들이 코드 개발 시, 탭 혹은 스페이스 선호도 투표 할 수 있는 빠른  애플리케이션을 API Gateway 및 AWS Lambda를 통해 만든 후, 이를 DynomoDB에 저장합니다. https://SOMEURL/ -d '{"vote": "spaces"}' 같은 간단한 엔드포인트가 될 것이고, 아래와 같은 간단한 SAM 템플릿 파일로 정의할 수 있습니다.

YAML
AWSTemplateFormatVersion : '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
  VotesTable:
    Type: "AWS::Serverless::SimpleTable"
  VoteSpacesTabs:
    Type: "AWS::Serverless::Function"
    Properties:
      Runtime: python3.6
      Handler: lambda_function.lambda_handler
      Policies: AmazonDynamoDBFullAccess
      Environment:
        Variables:
          TABLE_NAME: !Ref VotesTable
      Events:
        Vote:
          Type: Api
          Properties:
            Path: /
            Method: post

그래서  TABLE_NAME이라는 환경 변수를 통해 Lambda 함수에 드러내는 [dynamo_i] 테이블을 생성합니다. 이 템플릿이 유효한지 테스트하기 위해 sam validate를 호출하여, Valid를 반환 받으면 됩니다.

아래는 우리가 사용할 Lambda 함수 코드입니다.

Python
import os
import os
import json
import boto3
votes_table = boto3.resource('dynamodb').Table(os.getenv('TABLE_NAME'))

def lambda_handler(event, context):
    print(event)
    if event['httpMethod'] == 'GET':
        resp = votes_table.scan()
        return {'body': json.dumps({item['id']: int(item['votes']) for item in resp['Items']})}
    elif event['httpMethod'] == 'POST':
        try:
            body = json.loads(event['body'])
        except:
            return {'statusCode': 400, 'body': 'malformed json input'}
        if 'vote' not in body:
            return {'statusCode': 400, 'body': 'missing vote in request body'}
        if body['vote'] not in ['spaces', 'tabs']:
            return {'statusCode': 400, 'body': 'vote value must be "spaces" or "tabs"'}

        resp = votes_table.update_item(
            Key={'id': body['vote']},
            UpdateExpression='ADD votes :incr',
            ExpressionAttributeValues={':incr': 1},
            ReturnValues='ALL_NEW'
        )
        return {'body': "{} now has {} votes".format(body['vote'], resp['Attributes']['votes'])}

이제 로컬에서 테스트 해 봅시다. 실제 DynamoDB 데이터베이스를 만들어야 하고 환경 변수 TABLE_NAME을 통해 해당 데이터베이스의 이름을 제공해야 합니다. env.json 파일을 사용하여 본 작업을 수행 할 수 있습니다. 또는, 명령 줄에서 호출해서 만들 수 있습니다.

$ echo '{"httpMethod": "POST", "body": "{\"vote\": \"spaces\"}"}' |\
TABLE_NAME="vote-spaces-tabs" sam local invoke "VoteSpacesTabs"

Lambda 함수를 테스트하기 위해, sam local generate-event api  API를 사용하여 샘플 이벤트를 생성하고 이를 로컬 호출에 전달할 수 있습니다.  sam local start-api 을 통해 로컬 엔드 포인트를 말아서 모든 것을 테스트 할 수 있습니다.

$ curl -d '{ "vote": "tabs"}'http://127.0.0.1:3000/

그러면 다음과 같이 “tabs now has 12 votes”을 반환합니다.  만약 DynamoDB에 대한 로컬 테스트를 원하시면, DynamoDB Local 을 다운로드하고, 아래와 같이 로컬에서 시작할 수 있습니다.

 java -Djava.library.path =. / DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb

이제 Lambda 함수가 AWS_SAM_LOCAL 환경 변수를 사용하여 어떻게 행동할지 결정할 수 있습니다. 우리 함수를 약간 수정 해 봅시다.

Python
import os
import json
import boto3
if os.getenv("AWS_SAM_LOCAL"):
    votes_table = boto3.resource(
        'dynamodb',
        endpoint_url="http://docker.for.mac.localhost:8000/"
    ).Table("spaces-tabs-votes")
else:
    votes_table = boto3.resource('dynamodb').Table(os.getenv('TABLE_NAME'))

이제는 로컬 엔드 포인트를 사용하여 로컬 데이터베이스에 연결하므로 무선 랜 없이도 쉽게 작업 할 수 있습니다.

SAM local은 대화형 디버깅을 지원합니다. Java 및 Node.js에서 -d 플래그와 포트를 전달하여 디버거를 즉시 사용할 수 있습니다. 파이썬의 경우 import epdb; 와 같은 라이브러리를 사용할 수 있습니다. epdb.serve() 를 호출하고, sam local invoke -d 8080 "VoteSpacesTabs" 를 통해 디버거를 단계별로 실행하게 됩니다.

이제 먼저 aws cloudformation package의 별칭인 sam package 명령을 호출 한 다음이 명령의 결과를 sam deploy에 사용합니다.

$ sam package --template-file template.yaml --s3-bucket MYAWESOMEBUCKET --output-template-file package.yaml
Uploading to 144e47a4a08f8338faae894afe7563c3  90570 / 90570.0  (100.00%)
Successfully packaged artifacts and wrote output template to file package.yaml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file package.yaml --stack-name 
$ sam deploy --template-file package.yaml --stack-name VoteForSpaces --capabilities CAPABILITY_IAM
Waiting for changeset to be created..
Waiting for stack create/update to complete
Successfully created/updated stack - VoteForSpaces

이를 통해 API Gateway가 만들어집니다.

아래는 서비스가 라이브가 된 모습입니다. http://spaces-or-tabs.s3-website-us-east-1.amazonaws.com/

SAM Local 을 사용하면 서버리스 애플리케이션을 쉽게 테스트, 디버그 및 배포 할 수 있습니다. 본 소스 코드에 공헌하시려면, CONTRIBUTING.md 가이드 문서를 참고해 주시고, 좀 더 자세한 것은 기술 문서를 참고해 주시기 바랍니다.

Randall

이 글은 New – AWS SAM Local (Beta) – Build and Test Serverless Applications Locally의 한국어 번역 편집입니다.

AWS 주간 소식 모음 – 2017년 8월 13일

안녕하세요! 여러분~ 매주 월요일 마다 지난 주에 업데이트된 국내 AWS관련 콘텐츠를 정리해 드립니다. AWS 클라우드에 대한 새로운 소식을 확인하시는데 많은 도움 되시길 바랍니다. 혹시 빠지거나 추가할 내용이 있으시면, 저에게 메일 주시면 추가 공유해 드리겠습니다.

aws-korea-weekly

AWS코리아 블로그

AWS 관련 뉴스 및 추천 콘텐츠

AWS 글로벌 신규 소식 (영문)

AWS 제품별 블로그(영문)

AWS 주요 행사 및 온라인 세미나

AWS 공인 교육 일정

AWSKRUG 소모임

AWS 관련 새 소식을 확인하고 싶으시다면, 매주 업데이트 되는 AWS 주간 소식 모음을 살펴 보시기 바랍니다! 좀 더 빠르게 새소식을 접하시고 싶다면, 공식 트위터공식 페이스북을 팔로우 하세요!

이번 한주도 즐겁게 보내시고, 다음주에 다시 만나요!.

– AWS코리아 마케팅팀;

AWS 8월 온라인 세미나 – AWS 클라우드 소개, EC2 심층 분석, AWS 기반 데이터레이크 및 모바일앱 개발 등

AWS 클라우드를 아껴주시는 한국 고객 분들을 위해 지속적으로 AWS 월간 온라인 세미나 시리즈를 진행하고 있습니다.이번 8월 온라인 세미나 에서는 AWS 클라우드 소개, AWS  기반 데이터 레이크, Amazon EC2 Deep Dive,  모바일 앱 개발 A to Z 등 다양한  온라인 세미나를 준비하였습니다.

관심 있는 분들의 많은 참여를 바랍니다.

온라인 세미나 일정

비지니스 기초 | AWS와 함께하는 클라우드 컴퓨팅
연사: 한정수 AWS 어카운트 매니저
일시: 2017년 8월 29일 (화) 오전 10:00 – 오전 11:30

강연 요약: AWS 클라우드는 IT의 새로운 기준을 정립하며 클라우드 컴퓨팅 산업을 혁신하고 있습니다. 이 세미나에서는 클라우드 컴퓨팅의 개념과 AWS가 제공하는 서비스 및 솔루션의 특장점, 주요 사용사례에 대해 말씀드리고 질답 시간을 가질 예정입니다. 부디 참석하셔서 귀사의 사업과 서비스에 적용할 수 있는 정보를 얻어가시기 바랍니다.

발표 자료 및 영상 보기

기술 기초 | AWS 기반 데이터 레이크(Datalake) 구축 및 분석 실전
연사: 김민성 AWS 솔루션즈 아키텍트
일시: 2017년 8월 29일 (화) 오후 02:00 – 오후 03:30

강연 요약:   데이터레이크(Data Lake)를 사용하면 사전 정의 된 스키마를 적용 할 필요 없이 방대한 양의 데이터를 원래 형식으로 저장할 수 있으므로 훨씬 민첩하고 유연한 아키텍처가 가능할 뿐 아니라 데이터에서 새로운 유형의 분석 통찰력을 쉽게 얻을 수 있습니다. 본 세션에서 우리는 Data Lake의 핵심 개념과 AWS 환경을 기반으로한 구현 그리고 주요 고려 사항을 다룰 예정입니다.

발표 자료 및 영상 보기

기술 심화 | Amazon EC2 Deep Dive
연사: 이창수 AWS  솔루션즈 아키텍트
일시: 2017년 8월 30일(수) 오전 10:00 – 오전 11:30

강연 요약: Amazon EC2의 기초 개념과 클라우드 컴퓨팅으로 빠르고 가볍게 가상머신을 실행하는 법에 대해 알아봅니다. 또한 EC2 인스턴스의 종류와 Amazon Machine Image (AMI) 사용 방법, 이를 통해 손쉽게 인스턴스를 동적으로 제공하는 부트 스트래핑(Bootstrapping), 그리고 CloudWatch를 통한 EC2 모니터링 방법, 오토스케일링 (Autoscaling)으로 확장성 아키텍처를 구성하는 방법에 대해서 알아봅니다.

발표 자료 및 영상 보기

기술 심화 | AWS 기반 모바일 앱 개발: A to Z
연사: 윤석찬 AWS 테크에반젤리스트
일시: 2017년 8월 31일(목) 오후 2:00 – 오후 3:30

강연 요약: 모바일 앱 개발은 다양한 디바이스 및 개발 프레임워크와 백엔드 등으로 복잡도가 높아지고 있습니다. 이 세션에서는 AWS Mobile Hub를 통해 어떻게 클라우드 서비스를 빠르게 결합하여 매력적인 고품질 모바일 앱을 만들 수 있는지에 대해 알아봅니다. 모바일 앱 개발 뿐만 아니라, 테스팅을 위한 DeviceFarm, 메시징을 위한 SNS, 마케팅 캠페인 및 분석에 필요한 Pinpoint 같은 모바일 앱 운영 서비스에 대해서도 소개합니다. 최근 서버리스 환경의 모바일 개발을 위한 백엔드 아키텍처 및 React, EmberJS, AnglarJS와 Mobile Hub를 연결하는 샘플 아키텍처를 데모와 함께 살펴 봅니다.

발표 자료 및 영상 보기

8월 AWS 온라인 세미나를 통해 AWS를 통해 비지니스를 성공하는 방법과 다양한 AWS 서비스를 통해 다양한 IT 워크로드를 구축하는 방법에 대해 알아보시기 바랍니다. 또한, AWS Online Tech Talk 역시 매월 진행하고 있습니다. 영어로 진행되지만 많은 도움 받으시기 바랍니다.

– AWS 코리아 마케팅팀;

AWS 주간 소식 모음 – 2017년 8월 7일

안녕하세요! 여러분~ 매주 월요일 마다 지난 주에 업데이트된 국내 AWS관련 콘텐츠를 정리해 드리는 윤주리입니다. AWS 클라우드에 대한 새로운 소식을 확인하시는데 많은 도움 되시길 바랍니다. 혹시 빠지거나 추가할 내용이 있으시면, 저에게 메일 주시면 추가 공유해 드리겠습니다.

aws-korea-weekly

AWS코리아 블로그

AWS 관련 뉴스 및 추천 콘텐츠

AWS 글로벌 신규 소식 (영문)

AWS 제품별 블로그(영문)

AWS 주요 행사 및 온라인 세미나

AWS 공인 교육 일정

AWSKRUG 소모임

AWS 주요 파트너사 블로그

AWS 관련 새 소식을 확인하고 싶으시다면, 매주 업데이트 되는 AWS 주간 소식 모음을 살펴 보시기 바랍니다! 좀 더 빠르게 새소식을 접하시고 싶다면, 공식 트위터공식 페이스북을 팔로우 하세요!

이번 한주도 즐겁게 보내시고, 다음주에 다시 만나요!.

– AWS코리아 마케팅팀;

Amazon Lex의 신규 음성 입력 기능을 통한 Amazon Connect 연동하기

Amazon Connect는 셀프 서비스 클라우드 기반 콜센터 서비스로 저렴한 비용으로 더 나은 고객 서비스를 쉽게 제공있고, Amazon Lex는 음성 및 텍스트를 사용하여 대화식 인터페이스를 구축하는 서비스입니다.

이 두 가지 서비스를 통합하여, Lex 자동 음성 인식(ASR) 및 자연어 처리 및 인식(NLU) 기능을 활용하여, 고객에게 훌륭한 서비스 경험을 제공 할 수 있습니다. 두 가지 통합을 위해 Lex팀은 8kHz 음성 입력을 받을 수 있는 기능을 추가했습니다. 이를 통해 챗봇이 고객 요청의 대부분을 처리할 수 있게 되고, 고객들이 기다리는 시간도 줄일 수 있습니다.

이 글에서는 사용자가 고객 센터에 전화를 하고, Connect를 통해 들어온 음성 입력에 대해 Lex가 처리한 후, 이를 AWS Lambda 함수를 구성하는 코드를 살펴 보겠습니다. 샘플 예제는 ‘개발자들이 좋아하는 코드 편집기’에 대한 질문으로 미국 전화 번호 614-569-4019로 전화하여, 원하는 코드 편집기를 선택할 수 있습니다. (미국 번호라서 전화 비용이 들어갈 수도 있음을 양해 바랍니다.) 투표 결과는 http://best-editor-ever.s3-website-us-east-1.amazonaws.com/ 에서 볼 수 있습니다.


이 샘플 예제에 대해 간단하게 설명해 보겠습니다.

Amazon Lex
우선 Amazon Lex에서 VoteEditor라는 봇을 만들고, 여기에 원하는 코드 편집기를 투표할 수 있는 Slot을 만듭니다.

AWS Lambda

Lambda 함수도 매우 간단합니다. 먼저 투표를 저장하기 위해 Amazon DynamoDB 테이블을 생성합니다. 그런 다음 Lex(build_response)에 응답하는 헬퍼 메소드를 만들 것입니다. 이를 통해 Lex 기반 응답 형식으로 메시지를 감싸게 됩니다.


def lambda_handler(event, context):
    if 'ConnectToAgent' == event['currentIntent']['name']:
        return build_response("Ok, connecting you to an agent.")
    elif 'VoteEditor' == event['currentIntent']['name']:
        editor = event['currentIntent']['slots']['editor']
        resp = ddb.update_item(
            Key={"name": editor.lower()},
            UpdateExpression="SET votes = :incr + if_not_exists(votes, :default)",
            ExpressionAttributeValues={":incr": 1, ":default": 0},
            ReturnValues="ALL_NEW"
        )
        msg = "Awesome, now {} has {} votes!".format(
            resp['Attributes']['name'],
            resp['Attributes']['votes'])
        return build_response(msg)

코드를 잠깐 살펴 보면, 선택한 편집기에 대해 표가 없으면 1로 만들고, 편집기가 있으면 +1을 하는 코드로서   계속 진행하기 전에 Lex 콘솔을 통해 작동하는지 테스트 할 수 있습니다.

Amazon Connect
Amazon Contact Flow에서 Lex 봇을 사용하려면 먼저 Amazon Connect 인스턴스에 접근 권한이 있어야합니다.  콘솔에서 “Contact Flows”로 이동하여,  Lex 섹션에서 봇을 추가 할 수 있습니다.

이제 Amazon Connect 인스턴스가 Lex 봇을 호출 할 수 있게 되었으므로 Lex 봇을 포함하는 새로운 Contact Flow를 만들 수 있습니다. “Interact”카테고리에서 “Get customer input”위젯을 통해 봇을 추가합니다.

위젯을 사용하면 전화기의 숫자 키 또는 “Amazon Lex”탭에서 voiceinput을 가져 와서 Lex 서비스로 전달하기위한 “DTMF”탭을 사용할 수 있습니다. Lex 탭을 사용하여 몇 가지 구성을 사용합니다.

많은 옵션이 있지만, 사용하고자하는 봇 (봇의 버전 포함),  사용하려는 멘토,  소개글 등을 추가합니다. 최종 고객 요청 처리 흐름은 아래와 같습니다.

실생활에서 이러한 서비스 조합은 많은 부분을 구현할 수 있습니다. 실제 고객 상담원과 대화를 하기 전에, 사용자의 정보를 수집하고 대화에 필요한 정보를 수집할 수도 있습니다. Amazon Lex의 8KHz 음성 입력 기능을 통해서 좀 더 유연한 고객의 정보를 입력 받을 수 있다는 점은 매우 중요합니다.

마지막으로, Amazon Connect는 외부 개발자로 사용할 수 있는 것과 동일한 PostContent 엔드 포인트를 사용하므로 Lex에서 8kHz 기능을 활용하려면 Amazon Connect 사용자 일 필요는 없습니다.

좀 더 세부 사항은 기술 문서API 참조 문서를 살펴 보시기 바랍니다.

Randall

이 글은 New – Amazon Connect and Amazon Lex Integration 의 한국어 번역 편집본입니다.

MySQL에서 다운타임 거의 없이 DynamoDB로 마이그레이션하기

많은 고객들이 MySQL 과 같은 관계형 데이터베이스에서 Amazon DynamoDB으로 마이그레이션 하고자 합니다. 왜냐하면, 완전 관리형, 고성능, 높은 확장성과 유연성을 갖춘 NoSQL 데이터베이스 서비스이기 때문입니다.  DynamoDB의 경우, 트래픽 및 비즈니스 요구 사항에 따라 용량을 유연하게 증가 및 감소시킬 수 있기 때문에 서비스에 필요한 총 비용을 기존의 서버 기반의 RDBMS보다 더 쉽게 최적화 하는 것이 가능합니다.

하지만, 마이그레이션 작업은 통상적으로 다음과 같은 두 가지 이슈가 있을 수 있습니다:

  • 고객서비스가 반드시 24/7/365 가용 해야 할 경우 다운타임으로 인한 서비스 중단을 어떻게 최소화할 것인가?
  • RDBMS와 DynamoDB의 서로 다른 Key Design을 어떻게 반영할 것인가?

이 글에서는 다운타임을 최소화하면서 MySQL의 주요 DB 디자인을 NoSQL에 적합한 형태로 변환한 후,  MySQL의 기존 데이터를 DynamoDB로 원활하게 마이그레이션하는 두 가지 방법을 소개합니다.

마이그레이션을 위한 AWS 서비스 빌딩 블록
이 글에서 포함된 예제 코드들은 다음 AWS 서비스을 사용합니다:

  • AWS 데이터 마이그레이션 서비스(AWS DMS) 는 가장 범용적으로 사용되는 상용 및 오픈소스 데이터베이스 사이의 데이터 마이그레이션을 가능하게 해줍니다. AWS DMS는 서로 다른 데이터베이스 플랫폼 간의 동종 및 이종 데이터 마이그레이션을 지원합니다.
  • Amazon EMR은 방대한 양의 데이터를 신속하게 처리할 수 있도록 하는 관리형 Hadoop 프레임워크입니다. Hive 및 다른 비지니스 소프트웨어를 포함하는 이미 설정된 소프트웨어 스택들로 구성된 EMR 클러스터를 손쉽게 구축할 수 있습니다.
  • Amazon Kinesis는 실시간 트랜잭션, 로그 데이터, 클릭 스트림과 같은 방대한 양의 실시간 데이터를 최대 7일까지 지속적으로 저장하고 유지할 수 있습니다.
  • AWS Lambda는 서버를 준비하거나 운영하지 않고, 원하는 코드를 클라우드 상에서 직접 실행할 수 있도록 해 줍니다. AWS Lambda에서 실행되는 코드는 Amazon Kinesis Stream과 같은 다른 AWS 서비스들에 의해 자동으로 호출되도록 설정할 수 있습니다.

마이그레이션 방안

이 글에서는 다음 두가지 데이터 마이그레이션 옵션을 설명합니다.

  1.  AWS DMS 사용: AWS DMS는 DynamoDB 테이블을 타겟으로 마이그레이션을 지원합니다. 객체 매핑을 사용하여 마이그레이션 과정 중에 원본 데이터를 DynamoDB에서 요구하는 데이터 구조에 적합하게 재구성하는 것이 가능합니다.
  2. Amazon EMR, Kinesis 및 AWS Lambda 커스텀 스크립트 사용: 보다 복잡한 변환 과정 및 유연성이 요구될 때는 EMR, Kinesis, Lambda를 이용한 마이그레이션을 고려할 수 있습니다. MySQL 레코드를 더 적은 DynamoDB 항목으로 그룹화하고, 속성 이름을 동적으로 결정하고, 마이그레이션 중에 프로그래밍 방식으로 비즈니스 로직을 추가하고, 더 많은 데이터 유형을 지원하거나 하나의 큰 테이블에 대해 병렬 제어를 추가하려면 세분화된 사용자 제어가 필요합니다.

데이터 초기 적재 및 벌크 입력을 완료한 후에 가장 최근의 실시간 데이터를 CDC(Change Data Capture)로 처리하고 나면 최종적으로 애플리케이션이 DynamoDB를 바라보도록 설정을 변경하게 됩니다.

이 접근방법에서 변경데이터를 캡처하는 방법에 대한 상세한 내용은 AWS 데이터베이스 블로그 포스팅의 Streaming Changes in a Database with Amazon Kinesis에서 다루고 있습니다. 이 블로그 포스팅에서 사용한 모든 코드 및 테스트 코드는 big-data-blog GitHub 저장소를 통해 얻을 수 있습니다.

마이그레이션 솔루션 아키텍쳐

두 접근 방법의 전반적인 아키텍처는 다음과 같습니다.

방안 1:  AWS DMS 사용

이 절에서는 DMS를 이용하여 어떻게 MySQL 데이터베이스에 접속하고, 원본 데이터를 읽고, 데이터를 대상 DynamoDB 데이터베이스에 적재하기 위해 데이터를 정형화하는지에 대해 설명합니다.

1. 복제 인스턴스 생성 및 원본 및 대상 엔드포인트 설정하기

AWS Database Migration Service Best Practices를 참고하여 마이그레이션을 수행하기에 충분한 저장소와 처리능력을 갖춘 복제 인스턴스를 생성합니다. 예를 들어, 마이그레이션 대상 테이블이 많거나 동시에 여러 복제 작업을 수행할 계획이라면 더 큰 크기의 인스턴스들을 사용하는 것을 고려하여야 합니다. 데이터 복제 서비스는 상당한 양의 메모리와 CPU 리소스를 사용합니다.

MySQL 사용자 정보를 사용하여 MySQL에 접속하고 SUPER, REPLICATION CLIENT 권한으로 데이터를 추출합니다. MySQL 설정에서 Binary log를 활성화하고 CDC를 위해 binlog_format 파라미터를 ROW로 설정합니다. DMS를 사용하는 방법에 대한 더 상세한 정보는 AWS Database Migration Service 사용자 가이드의 Getting Started 문서를 참조합니다.

mysql> CREATE USER 'repl'@'%' IDENTIFIED BY 'welcome1'; mysql> GRANT all ON <database name>.* TO 'repl'@'%'; mysql> GRANT SUPER,REPLICATION CLIENT ON *.* TO 'repl'@'%';

DMS에서 DynamoDB 데이터베이스를 대상으로 설정하기 전에, DMS가 사용할 IAM Role을 생성하고 DynamoDB 대상 테이블에 접근할 권한을 부여해야 합니다. 원본 및 대상 데이터베이스에 접근할 엔드포인트들도 다음 스크린샷과 같이 설정합니다.

다음 스크린샷은 source-mysql의 상세 정보 화면입니다.

객체 매핑 규칙 설정 및 작업 생성하기

다음 예제에서는, MySQL 테이블이 복합 프라이머리 키( customer id + ordered + productid )를 가지고 있다고 가정합니다. 이와 같은 경우, 객체 매핑 규칙을 사용하여 DynamoDB에서 요구하는 데이터 구조에 적합하게 키를 재구성할 수 있습니다.

여기에서는 대상 DynamoDB 테이블은 customer idorder id 컬럼의 조합을 hash key로 설정하고 product id 컬럼을 sort key로 설정합니다. 하지만, 실제 마이그레이션 상황에서는 데이터 적재 및 접근 패턴에 따라 파티션 키를 결정해야 합니다. 보통 카디널리티가 높은 속성을 파티션키로 사용하게 됩니다. DynamoDB에서 올바른 파티션 키를 결정하는 방법에 대한 상세한 내용은 Choosing the Right DynamoDB Partition Key 블로그를 참조하십시오.

여기서 rule-action을 map-record-to-record로 설정하였고 해당 컬럼을 제외 대상 컬럼(exclude-columns) 속성 리스트에 포함시키지 않았기 때문에, DMS 서비스는 원본 데이터의 quantity 컬럼을 대상 DynamoDB 테이블에 자동으로 생성합니다. map-record-to-recordmap-record-to-document 설정에 대한 상세 내용은 AWS Database Migration Service에서 Amazon DynamoDB 데이터베이스를 대상으로 사용 문서를 참조하십시오.

마이그레이션은 작업 생성시 Start task on create 옵션을 해제하지 않을 경우, 작업이 생성되는 즉시 시작됩니다. 마이그레이션 작업이 백그라운드에서 수행되는 동안 어떤 일이 발생하는지 확인하기 위하여 enabling logging을 선택하는 것을 추천합니다.

다음 스크린샷은 작업 생성 페이지를 보여줍니다.

콘솔에서 마이그레이션 개별 데이터베이스 테이블과 마이그레이션에 필요한 변환을 포함한 스키마를 지정할 수 있습니다. Guided 탭의 Where 항목에서 스키마, 테이블을 설정하고 Action 항목에서 포함/불포함 여부를 설정합니다. Filter 항목에서 테이블 내의 컬럼명 및 적용할 조건을 설정합니다.

테이블 매핑 정보는 JSON 형태로 생성할 수도 있습니다. JSON 탭에서 Enable JSON editing 체크박스를 선택하십시오.

다음은 원본데이터가 대상 테이블의 어디에 위치할지 결정하는 객체 매핑 규칙에 대한 예제입니다. 아래 예제를 복사하여 사용할 경우, 아래 속성들을 실제 사용하는 값으로 변경해야 합니다. 보다 많은 예제들은 AWS Database Migration Service에서 Amazon DynamoDB 데이터베이스를 대상으로 사용 문서를 참조하십시오.

  • schema-name
  • table-name
  • target-table-name
  • mapping-parameters
  • attribute-mappings
{
  "rules": [
   {
      "rule-type": "selection",
      "rule-id": "1",
      "rule-name": "1",
      "object-locator": {
        "schema-name": "mydatabase",
        "table-name": "purchase"
      },
      "rule-action": "include"
    },
    {
      "rule-type": "object-mapping",
      "rule-id": "2",
      "rule-name": "2",
      "rule-action": "map-record-to-record",
      "object-locator": {
        "schema-name": "mydatabase",
        "table-name": "purchase"
 
      },
      "target-table-name": "purchase",
      "mapping-parameters": {
        "partition-key-name": "customer_orderid",
        "sort-key-name": "productid",
        "exclude-columns": [
          "customerid",
          "orderid"           
        ],
        "attribute-mappings": [
          {
            "target-attribute-name": "customer_orderid",
            "attribute-type": "scalar",
            "attribute-sub-type": "string",
            "value": "${customerid}|${orderid}"
          },
          {
            "target-attribute-name": "productid",
            "attribute-type": "scalar",
            "attribute-sub-type": "string",
            "value": "${productid}"
          }
        ]
      }
    }
  ]
}

마이그레이션 작업 시작하기
만약 target-table-name 속성에 정의된 대상 테이블이 DynamoDB에 존재하지 않을 경우, DMS는 데이터 변환 참조와 추가 주제를 포함하는 AWS Database Migration Service 참조 문서에서 설명하는 원본 데이터 형식대상 데이터 형식에  대한 데이터형 변환 규칙에 따라 테이블을 생성합니다. 마이그레이션 작업의 진행상황을 모니터링하는 많은 지표들이 제공됩니다. 보다 상세한 모니터링 관련 정보는 AWS Database Migration Service 작업 모니터링 문서에서 확인하실 수 있습니다.

다음 스크린샷은 CloudWatch Logs에 기록된 이벤트들과 오류 샘플입니다.

마이그레이션에 사용한 DMS 복제 인스턴스들은 모든 마이그레이션 작업이 완료된 후에는 삭제되어야 합니다. 보유기간이 경과한 Cloudwatch log들은 자동으로 삭제됩니다.

방안 2: EMR, Amazon Kinesis, Lambda 사용

이 절에서는 보다 정교한 제어와 유연성을 제공하기 위하여 EMR과 Amazon Kinesis, Lamdba를 사용하는 다른 방안에 대해 다룹니다. 만약 작업환경에 MySQL replica가 포함된다면, replica로부터 데이터를 마이그레이션하는 것을 추천합니다.

키 디자인 변경하기
데이터베이스를 RDBMS에서 NoSQL로 변경하기로 결정했다면, 성능 및 비용 효율성을 위해서 데이터 키를 NoSQL에 더 적합하도록 설계할 필요가 있습니다.

방안 #2에서는 방안 #1과 비슷하게 MySQL 데이터베이스 원본이 복합 프라이머리 키 (customerid + orderid + productid)를 가지고 있다고 가정합니다. 하지만, 여기서는 MySQL 레코드들을 customerid(hash key)와 orderid(sort key)를 사용하여 더 적은 DynamoDB 아이템들로 그룹화합니다. 이를 위하여, MySQL의 복합키 중 마지막 컬럼 (productid)을 복합키에서 제거하는 대신 DynamoDB의 속성 이름으로 하고, Quantity 컬럼을 해당 속성의 값으로  변환합니다.

이런 변환법을 통해 전체 아이템의 수를 줄일 수 있으며, 같은 양의 정보를 더 적은 RCU(Read Capacity Unit)을 사용하여 조회할 수 있어 비용을 절감하면서 더 나은 성능을 얻을 수 있습니다. RCU/WCU(Read Capacity Unit/Write Capacity Unit)를 어떻게 계산하는지에 대한 더 상세한 정보는 프로비저닝된 처리량 문서를 확인하시기 바랍니다.

단계별 마이그레이션

방안 #2는 다음 두 단계의 마이그레이션이 동시에 진행됩니다.:

  • 일괄 처리: MySQL 데이터 export, export파일의 S3 업로드, S3 데이터 DynamoDB에 import
  • 실시간 처리: MySQL의 변경 데이터 캡처, insert/update/delete 트랜잭션을 Kinesis Stream에 송신, DynamoDB에 데이터를 입력하기 위한 Lambda 함수 호출.

데이터의 일관성과 무결성을 유지하기 위해 데이터를 캡처하고 Amazon Kinesis Stream에 밀어넣는 작업은 일괄 처리 프로세스 전에 시작되어야 하고, EMR에서 처리되는 일괄처리 프로세스가 종료되기 전까지 Lambda 함수는 실행되지 않고 캡처된 데이터가 스트림에 유지되어야 합니다. 다음 순서와 같이 진행됩니다.:

  1. Amazon Kinesis Stream에 대해 데이터 실시간 처리를 시작합니다.
  2. 실시간 처리 프로세스가 시작되자마자, 일괄 처리 프로세스를 시작합니다.
  3. 일괄 처리 프로세스가 완료되면 Amazon Kinesis Stream으로 부터 데이터를 추출하여 DynamoDB에 put_item 함수를 실행하는 Lambda 함수를 호출합니다.
  4. 애플리케이션의 엔드포인트를 MySQL에서 DynamoDB를 바라보도록 설정을 변경합니다.

단계 1:  변경데이터캡처및 Amazon Kinesis Streams에밀어넣기

먼저, MySQL으로부터 트렌젝션 데이터를 캡처할 Amazon Kinesis Stream을 생성합니다. Data retention period 값을 일괄 처리 프로세스의 예상 처리시간에 맞춰 설정합니다. 데이터 무결성을 위해서는 데이터 보관 기간을 일괄 처리 프로세스가 실행되는 기간 동안 발생하는 모든 트랜잭션을 보관하기 충분할 정도로 길게 설정해야 하지만, 보관 기간을 반드시 최대값으로 설정할 필요는 없습니다. 마이그레이션 대상 데이터의 양에 따라 설정합니다.

MySQL 설정에서, BinLogStreamReader 모듈이 트랜잭션 데이터를 캡처할수 있도록 binlog_format 설정값을 ROW로 설정합니다. Binlog를 활성화하려면 log_bin 매개변수도 설정되어야 합니다. 더 상세한 내용은 AWS 데이터베이스 블로그의 Streaming Changes in a Database with Amazon Kinesis 포스트를 참조하시기 바랍니다.

[mysqld]
secure-file-priv = ""
log_bin=/data/binlog/binlog
binlog_format=ROW
server-id = 1
tmpdir=/data/tmp

다음 예제 코드는 트랜잭션 데이터를 캡처하여 Amazon Kinesis Stream으로 밀어넣는 Python 예제 코드입니다.

#!/usr/bin/env python
from pymysqlreplication import BinLogStreamReader
from pymysqlreplication.row_event import (
  DeleteRowsEvent,
  UpdateRowsEvent,
  WriteRowsEvent,
)

def main():
  kinesis = boto3.client("kinesis")

  stream = BinLogStreamReader(
    connection_settings= {
      "host": "<host IP address>",
      "port": <port number>,
      "user": "<user name>",
      "passwd": "<password>"},
    server_id=100,
    blocking=True,
    resume_stream=True,
    only_events=[DeleteRowsEvent, WriteRowsEvent, UpdateRowsEvent])

  for binlogevent in stream:
    for row in binlogevent.rows:
      event = {"schema": binlogevent.schema,
      "table": binlogevent.table,
      "type": type(binlogevent).__name__,
      "row": row
      }

      kinesis.put_record(StreamName="<Amazon Kinesis stream name>", Data=json.dumps(event), PartitionKey="default")
      print json.dumps(event)

if __name__ == "__main__":
main()

다음 코드는 위 Python 스크립트에 의해 생성된 JSON 데이터 예제입니다. 각 트랜잭션은 JSON 데이터에 다음과 같은 type 속성으로 기록됩니다:

  • WriteRowsEvent = INSERT
  • UpdateRowsEvent = UPDATE
  • DeleteRowsEvent = DELETE
{"table": "purchase_temp", "row": {"values": {"orderid": "orderidA1", "quantity": 100, "customerid": "customeridA74187", "productid": "productid1"}}, "type": "WriteRowsEvent", "schema": "test"}
{"table": "purchase_temp", "row": {"before_values": {"orderid": "orderid1", "quantity": 1, "customerid": "customerid74187", "productid": "productid1"}, "after_values": {"orderid": "orderid1", "quantity": 99, "customerid": "customerid74187", "productid": "productid1"}}, "type": "UpdateRowsEvent", "schema": "test"}
{"table": "purchase_temp", "row": {"values": {"orderid": "orderid100", "quantity": 1, "customerid": "customerid74187", "productid": "productid1"}}, "type": "DeleteRowsEvent", "schema": "test"}

단계 2. MySQL에서 DynamoDB로 데이터 덤프하기

DMS를 사용하는 가장 손쉬운 방법 중 하나는, 최근 추가된 Amazon S3를 마이그레이션 대상으로 사용하는 것입니다. S3를 대상으로 할 경우, full load 및 CDC 데이터가 CSV 형식으로 저장됩니다. 그러나, CDC의 경우에는 UPDATE 및 DELETE 문의 지원되지 않아 마이그레이션에 적합하지 않습니다. 보다 상세한 내용은 AWS Database Migration Service에서 Amazon S3를 대상으로 사용 문서를 참조하십시오.

Amazon S3로 데이터를 업로드하는 다른 방법은 스크립트에서 INTO OUTFILE SQL 절과 aws s3 sync CLI 명령어를 병렬로 사용하는 것입니다. 병렬 처리 수준은 서버 용량 및 로컬 네트워크 대역폭에 따라 달라집니다. pt-archiverPercona Toolkit 에 포함된 도구입니다. 상세 내용은 appendix를 참조하십시오. )와 같은 3rd party 도구도 유용하게 사용할 수 있습니다.

SELECT * FROM purchase WHERE <condition_1>
INTO OUTFILE '/data/export/purchase/1.csv' FIELDS TERMINATED BY ',' ESCAPED BY '\\' LINES TERMINATED BY '\n';
SELECT * FROM purchase WHERE <condition_2>
INTO OUTFILE '/data/export/purchase/2.csv' FIELDS TERMINATED BY ',' ESCAPED BY '\\' LINES TERMINATED BY '\n';
...
SELECT * FROM purchase WHERE <condition_n>
INTO OUTFILE '/data/export/purchase/n.csv' FIELDS TERMINATED BY ',' ESCAPED BY '\\' LINES TERMINATED BY '\n';

여기에서 다루는 사용사례의 경우 aws s3 sync 명령어를 추천합니다. 이 명령어는 내부적으로 S3 multipart 업로드기능을 사용하여 동작하고 패턴 매칭을 통해 특정파일을 포함하거나 제외시킬 수 있습니다. 또한, sync 명령어는 로컬 버전과 S3 버전 간에 파일 크기와 수정시간을 비교하여 서로 다른 경우에만 동기화를 수행하기 때문에 동기화 프로세스가 처리 도중에 중단되더라도 동일한 파일을 다시 업로드할 필요가 없습니다. 더 상세한 내용은 AWS CLI 명령어 참조문서의 sync command를 참고하시기 바랍니다.

$ aws s3 sync /data/export/purchase/ s3://<your bucket name>/purchase/ 
$ aws s3 sync /data/export/<other path_1>/ s3://<your bucket name>/<other path_1>/
...
$ aws s3 sync /data/export/<other path_n>/ s3://<your bucket name>/<other path_n>/ 

모든 데이터가 S3로 업로드된 후, 데이터를 DynamoDB에 밀어넣기 위해서는 다음과 같은 두가지 방법이 있습니다.:

  • 외부 테이블을 이용하여 Hive사용
  • MapReduce 코드 작성

외부 테이블을 이용하여 Hive 사용

S3의 데이터에 대해서 Hive 외부테이블을 생성하고 org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler 속성을 사용하여 생성한 DynamoDB 테이블을 대상으로 하는 다른 외부 테이블에 S3와 연결된 외부 테이블의 내용을 밀어넣습니다. 더 나은 생산성과 확장성을 위해 Hive용 UDF 모음인 Brickhouse를 사용하는 것을 고려해 볼 수 있습니다.

다음 샘플 코드는 DynamoDB용 Hive 테이블이 ARRAY<STRING> 타입의 products 컬럼으로 생성되었다고 가정합니다. Productidquantity 컬럼은 customeridorderid별로 그룹화되어 Brickhouse에서 제공하는 CollectUDAF 컬럼을 사용하여 products 컬럼에 삽입됩니다.

hive> DROP TABLE purchase_ext_s3; 
--- To read data from S3 
hive> CREATE EXTERNAL TABLE purchase_ext_s3 (
customerid string,
orderid    string,
productid  string,
quantity   string) 
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' 
LOCATION 's3://<your bucket name>/purchase/';

Hive> drop table purchase_ext_dynamodb ; 
--- To connect to DynamoDB table  
Hive> CREATE EXTERNAL TABLE purchase_ext_dynamodb (
      customerid STRING, orderid STRING, products ARRAY<STRING>)
      STORED BY 'org.apache.hadoop.hive.dynamodb.DynamoDBStorageHandler' 
      TBLPROPERTIES ("dynamodb.table.name" = "purchase", 
      "dynamodb.column.mapping" = "customerid:customerid,orderid:orderid,products:products");

--- Batch-puts to DynamoDB using Brickhouse 
hive> add jar /<jar file path>/brickhouse-0.7.1-SNAPSHOT.jar ; 
hive> create temporary function collect as 'brickhouse.udf.collect.CollectUDAF';
hive> INSERT INTO purchase_ext_dynamodb 
select customerid as customerid , orderid as orderid
       ,collect(concat(productid,':' ,quantity)) as products
      from purchase_ext_s3
      group by customerid, orderid; 

불행히도 DynamoDBStorageHandler클래스는 MAP, LIST, BOOLEAN 및 NULL  데이터형을 지원하지 않기 때문에 ARRAY<STRING> 데이터형을 선택하였습니다. Hive의 ARRAY<STRING> 형식의 products 컬럼은 DynamoDB의 StringSet데이터형 속성으로 변환됩니다. 샘플코드는 Brickhouse가 어떤 식으로 동작하는지, 어떻게 원하는 복수의 레코드들을 골라 DynamoDB의 하나의 StringSet  데이터형 속성으로 병합할 수 있는지 보여줍니다.

Hadoop Streaming으로 Python MarReduce 코드 작성하기
맵퍼 작업은 S3의 입력데이터로부터 각 레코드를 읽고 입력 키-값 쌍을 중간 키-값 쌍으로 매핑합니다. S3의 원본 데이터를 탭 문자(“\t)로 구분된 키 부분과 값 부분의 두 부분으로 나눕니다. 맵퍼 데이터는 중간 키(customeridorderid) 값으로 정렬되어 reducer로 전송됩니다. reducer단계에서 각 레코드들이 DynamoDB에 저장합니다.

#!/usr/bin/env python
import sys
 
# get all lines from stdin
for line in sys.stdin:
    line = line.strip()
    cols = line.split(',')
# divide source data into Key and attribute part.
# example output : “cusotmer1,order1	product1,10”
    print '%s,%s\t%s,%s' % (cols[0],cols[1],cols[2],cols[3] )

일반적으로 reduce 작업은 매핑( 키 / 값 목록의 쌍 ) 프로세스가 생성한 결과값을 수신한 뒤 각 키에 대해 값의 목록에 대한 작업을 수행합니다.

여기서는 reducer를 STDIN/STDOUT/Hadoop streaming을 기반으로 하여 Python으로 작성하였습니다. 문제는 이와 같은 경우 열거형 데이터 형식을 사용할 수 없다는 것입니다. 이와 같은 경우 reducer를 매퍼의 중간 키값 – 이 경우, customeridoerderid(cols[0],cols[1]) -으로 정렬된 데이터를 수신하고 모든 속성을 item_data dictionary의 특정 키로 저장합니다. Item_data dictionary의 속성들은 sys.stdin에서 새 중간 키가 들어올 대마다 DynamoDB에 입력되거나 플러싱됩니다.

#!/usr/bin/env python
import sys
import boto.dynamodb
 
# create connection to DynamoDB
current_keys = None
conn = boto.dynamodb.connect_to_region( '<region>', aws_access_key_id='<access key id>', aws_secret_access_key='<secret access key>')
table = conn.get_table('<dynamodb table name>')
item_data = {}

# input comes from STDIN emitted by Mapper
for line in sys.stdin:
    line = line.strip()
    dickeys, items  = line.split('\t')
    products = items.split(',')
    if current_keys == dickeys:
       item_data[products[0]]=products[1]  
    else:
        if current_keys:
          try:
              mykeys = current_keys.split(',') 
              item = table.new_item(hash_key=mykeys[0],range_key=mykeys[1], attrs=item_data )
              item.put() 
          except Exception ,e:
              print 'Exception occurred! :', e.message,'==> Data:' , mykeys
        item_data = {}
        item_data[products[0]]=products[1]
        current_keys = dickeys

# put last data
if current_keys == dickeys:
   print 'Last one:' , current_keys #, item_data
   try:
       mykeys = dickeys.split(',')
       item = table.new_item(hash_key=mykeys[0] , range_key=mykeys[1], attrs=item_data )
       item.put()
   except Exception ,e:
print 'Exception occurred! :', e.message, '==> Data:' , mykeys

MapReduce 작업을 실행하려면 EMR 마스터 노드에 접속하여 Hadoop 스트리밍 작업을 실행하십시오. hadoop-streaming.jar 파일 위치 및 파일 이름은 EMR 버전에 따라 다를 수 있습니다. reducer가 실행되는 동안 발생하는 exception 메시지들은 -output 옵션으로 지정한 디렉토리에 저장됩니다. 예외 또는 오류의 원인이되는 데이터를 식별하기 위해 해시 키 및 범위 키 값들도 기록됩니다.

$ hadoop fs -rm -r s3://<bucket name>/<output path>
$ hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar \
           -input s3://<bucket name>/<input path> -output s3://<bucket name>/<output path>\
           -file /<local path>/mapper.py -mapper /<local path>/mapper.py \
           -file /<local path>/reducer.py -reducer /<local path>/reducer.py

위 스크립트와 자체 생성한 테스트 데이터를 사용하여 수행한 마이그레이션 테스트에서 데이터베이스 크기 및 데이터 마이그레이션을 완료하기까지 걸린 시간은 다음과 같습니다.

Server MySQL instance m4.2xlarge
EMR cluster master : 1 x m3.xlarge

core  : 2 x m4.4xlarge

DynamoDB 2000 write capacity unit
Data Number of records 1,000,000,000
Database file size (.ibc) 100.6 GB
CSV files size 37 GB
Performance (time) Export to CSV 6 min 10 sec
Upload to S3 (sync) 3 min 30 sec
Import to DynamoDB depending on write capacity unit

다음 스크린샷은 마이그레이션 작업 도중 write capacity 사용 결과를 보여줍니다.

성능 결과는 사용한 서버 용량과 네트워크 대역폭, 병렬 처리 수준, 변환 로직, 사용 프로그램 언어 및 기타 조건에 달라질 수 있습니다. 이 경우 프로비저닝된 write capacity unit이 모두 데이터 import를 위해 사용한 MapReduce 작업에 의해 소비되었으므로, EMR 클러스터의 크기 및 DynamoDB 테이블의 write capacity unit을 늘릴 수록 데이터 이전작업 완료에 걸리는 시간을 단축할 수 있습니다. Jave 기반 MapReduce 코드를 사용할 경우 MapReduce 프레임워크 사용 및 함수 작성시 보다 많은 유연성을 제공합니다.

단계 3: Amazon Lambda 함수를 사용하여 Amazon Kinesis로부터 데이터를 읽고 DynamoDB에 업데이트하기

AWS Lambda 콘솔에서 Create a Lambda functionkinesis-process-record-python blueprint를 선택합니다. 다음 버튼을 클릭하고 Configure triggers 페이지에서 생성한 Kinesis stream을 선택합니다.

생성한 Lambda 함수가 Amazon Kinesis 스트림을 읽고 데이터를 DynamoDB에 쓸 수 있도록 해당 권한을 가진 IAM role을 설정하여야 합니다.

Lambda 함수는 각 레코드의 type 속성을 확인하여 트랜잭션 유형을 식별합니다. 트랜잭션 유형에 따라 변환 및 업데이트 방법이 결정됩니다.

예를 들어 JSON 레코드가 함수에 전달되면 함수는 type 속성을 확인하고 DynamoDB 테이블에 들어온 레코드와 동일한 키를 가진 아이템이 이미 존재하는지 확인합니다. 만약 동일한 키를 가진 아이템이 이미 있다면 기존 아이템을 조회하여 dictionary 변수 (다음 코드에서는 item 변수)에 저장하고 DynamoDB 테이블에 저장하기 전에 dictionary 변수에 저장된 기존 아이템 정보에 새로 전달된 정보를 반영하여 저장합니다. 이렇게 해서 들어오는 레코드가 기존 항목을 덮어 쓰지 않도록 합니다.

from __future__ import print_function

import base64
import json
import boto3

print('Loading function')
client = boto3.client('dynamodb')

def lambda_handler(event, context):
    #print("Received event: " + json.dumps(event, indent=2))
    for record in event['Records']:
        # Amazon Kinesis data is base64-encoded so decode here
        payload = base64.b64decode(record['kinesis']['data'])
        print("Decoded payload: " + payload)
        data = json.loads(payload)
        
        # user logic for data triggered by WriteRowsEvent
        if data["type"] == "WriteRowsEvent":
            my_table = data["table"]
            my_hashkey = data["row"]["values"]["customerid"]
            my_rangekey = data["row"]["values"]["orderid"]
            my_productid = data["row"]["values"]["productid"]
            my_quantity = str( data["row"]["values"]["quantity"] )
            try:
                response = client.get_item( Key={'customerid':{'S':my_hashkey} , 'orderid':{'S':my_rangekey}} ,TableName = my_table )
                if 'Item' in response:
                    item = response['Item']
                    item[data["row"]["values"]["productid"]] = {"S":my_quantity}
                    result1 = client.put_item(Item = item , TableName = my_table )
                else:
                    item = { 'customerid':{'S':my_hashkey} , 'orderid':{'S':my_rangekey} , my_productid :{"S":my_quantity}  }
                    result2 = client.put_item( Item = item , TableName = my_table )
            except Exception, e:
                print( 'WriteRowsEvent Exception ! :', e.message  , '==> Data:' ,data["row"]["values"]["customerid"]  , data["row"]["values"]["orderid"] )
        
        # user logic for data triggered by UpdateRowsEvent
        if data["type"] == "UpdateRowsEvent":
            my_table = data["table"]
            
        # user logic for data triggered by DeleteRowsEvent    
        if data["type"] == "DeleteRowsEvent":
            my_table = data["table"]
            
            
    return 'Successfully processed {} records.'.format(len(event['Records']))

단계 4:  애플리케이션 엔드포인트를 MySQL에서 DynamoDB로 변경하기

애플리케이션이 MySQL 대신 DynamoDB를 데이터베이스로 사용하려면 애플리케이션 코드를 리팩토링해야 합니다. 애플리케이션의 데이터베이스 액세스에 대한 모든 경우를 여기에서 다루기는 어렵기 때문에, 여기서는 다음의 간단한 자바 코드로 데이터베이스 연결 및 쿼리 부분이 어떻게 바뀌어야 하는지 확인해 보겠습니다. 더 자세한 내용에 대해서는 DynamoDB 및 AWS SDK를 사용한 프로그래밍 문서를 참조하시기 바랍니다.

MySQL 쿼리 코드 예제

다음 샘플 코드는 MySQL 데이터베이스에 연결하고 데이터를 조회하는 일반적인 방법을 보여줍니다.

import java.sql.* ;
...
try {
    Connection conn =  DriverManager.getConnection("jdbc:mysql://<host name>/<database name>" , "<user>" , "<password>");
    stmt = conn.createStatement();
    String sql = "SELECT quantity as quantity FROM purchase WHERE customerid = '<customerid>' and orderid = '<orderid>' and productid = '<productid>'";
    ResultSet rs = stmt.executeQuery(sql);

    while(rs.next()){ 
       int quantity  = rs.getString("quantity");   //Retrieve by column name 
       System.out.print("quantity: " + quantity);  //Display values 
       }
} catch (SQLException ex) {
    // handle any errors
    System.out.println("SQLException: " + ex.getMessage());}
...
==== Output ====
quantity:1

DynamoDB 쿼리 코드 예제

DynamoDB에서 데이터를 조회하려면 다음 단계를 따르면 됩니다:

  1. AmazonDynamoDBClient 및 ProfileCredentialProvider를 이용하여 DynamoDB 클래스의 인스턴스 생성
  2. DynamoDB 클래스 인스턴스의 getTable method를 사용하여 대상 Table 클래스 인스턴스 획득
  3. withHashKey및 withRangeKeyCondition method를 사용하여 QuerySpec 클래스 인스턴스 생성
  4. QuerySpec 클래스 인스턴스를 사용하여 Table 클래스 인스턴스의 query method를 실행. 결과값이 JSON 형식으로 반환되므로, 결과값에 대하여 특정 속성 값을 확인하기 위하여 getJSON method 사용
...
DynamoDB dynamoDB = new DynamoDB( new AmazonDynamoDBClient(new ProfileCredentialsProvider()));

Table table = dynamoDB.getTable("purchase");

QuerySpec querySpec = new QuerySpec()
        .withHashKey("customerid" , "customer1")  // hashkey name and its value 
        .withRangeKeyCondition(new RangeKeyCondition("orderid").eq("order1") ) ; // Ranage key and its condition value 

ItemCollection<QueryOutcome> items = table.query(querySpec); 

Iterator<Item> iterator = items.iterator();          
while (iterator.hasNext()) {
Item item = iterator.next();
System.out.println(("quantity: " + item.getJSON("product1"));   // 
}
...
==== Output ====
quantity:1

맺음말
이 글에서는 MySQL에서 DynamoDB로 데이터를 원활하게 마이그레이션하고 마이그레이션 중 중단 시간을 최소화하기 위한 두 가지 방안을 소개했습니다. 방안 #1에서는 DMS를 사용하였고, 방안 #2에서는 EMR, Amazon Kinesis 및 Lambda를 복합적으로 사용하였습니다. 또한 각 데이터베이스의 특성에 따라 키 디자인을 변환하여 읽기 및 쓰기 성능을 개선하고 비용을 절감하는 방법도 설명했습니다. 각 방안은 서로 장단점이 있으므로 비즈니스 요구 사항에 따라 어떤 접근방법을 취할지 고려할 필요가 있습니다.

여기에서 사용한 예제 코드들은 다양한 환경에서 완벽하고 효율적이며 신뢰할 수 있는 데이터 마이그레이션 용으로 재사용되기에 충분한 수준이 아닙니다. 데이터 마이그레이션을 시작하기 전에 참조용으로 사용하시고 실제 마이그레이션에서는 신뢰할 수 있는 마이그레이션을 수행할 수 있도록 모든 요소들을 충분히 고려하여 작성되어야 합니다.

이 글이 여러분의 데이터베이스 마이그레이션을 계획 및 구현하고 서비스 중단을 최소화하는데 도움이 되기를 바랍니다.

Appendix

Percona Toolkit 설치법:

# Install Percona Toolkit
$ wget https://www.percona.com/downloads/percona-toolkit/3.0.2/binary/redhat/6/x86_64/percona-toolkit-3.0.2-1.el6.x86_64.rpm
$ yum install perl-IO-Socket-SSL
$ yum install perl-TermReadKey
$ rpm -Uvh percona-toolkit-3.0.2-1.el6.x86_64.rpm

Pt-archiver 실행 예제:

# run pt-archiver
$ pt-archiver –source h=localhost,D=blog,t=purchase –file ‘/data/export/%Y-%m-%d-%D.%t’  –where “1=1” –limit 10000 –commit-each

이 글은 AWS 빅데이터 서비스의 기술 지원 엔지니어인 이용성님이 작성하신 글 Near Zero Downtime Migration from MySQL to DynamoDB을 AWS 솔루션즈 아키텍트인 김병수님이 번역해 주셨습니다.

AWS 주간 소식 모음 – 2017년 7월 31일

안녕하세요! 여러분~ 매주 월요일 마다 지난 주에 업데이트된 국내 AWS관련 콘텐츠를 정리해 드립니다. AWS 클라우드에 대한 새로운 소식을 확인하시는데 많은 도움 되시길 바랍니다. 혹시 빠지거나 추가할 내용이 있으시면, 저에게 메일 주시면 추가 공유해 드리겠습니다.

aws-korea-weekly

AWS코리아 블로그

AWS코리아 발표 자료

AWS코리아 동영상

AWS 관련 뉴스 및 추천 콘텐츠

AWS 글로벌 신규 소식 (영문)

AWS 제품별 블로그(영문)

AWS 주요 행사 및 온라인 세미나

AWS 공인 교육 일정

AWSKRUG 소모임

AWS 주요 파트너사 블로그

AWS 관련 새 소식을 확인하고 싶으시다면, 매주 업데이트 되는 AWS 주간 소식 모음을 살펴 보시기 바랍니다! 좀 더 빠르게 새소식을 접하시고 싶다면, 공식 트위터공식 페이스북을 팔로우 하세요!

이번 한주도 즐겁게 보내시고, 다음주에 다시 만나요!.

– AWS코리아 마케팅팀;