성공적인 게임 런칭을 위한 비밀의 레시피 #3

112
Amazed By AWS Series #3 Real-time Analytics 정윤진 솔루션 아키텍트 [email protected]

Upload: amazon-web-services-korea

Post on 12-Jul-2015

1.219 views

Category:

Technology


11 download

TRANSCRIPT

Page 1: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Amazed By AWS Series #3

Real-time Analytics

정윤진 솔루션 아키텍트 [email protected]

Page 2: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

소개

AWS 솔루션 아키텍트

Gaming/HPC

DevOps

System Admin

(십년전) Kernel driver dev.

잘은 모르지만 Unity를

사랑합니다.

Page 3: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

오늘 내용

a. INTRO – Ice breaking

b. Amazon Kinesis

c. Amazon Redshift

d. Amazon EMR f. Case, Demo

Page 4: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

시작하기 전에.

Page 5: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

AWS 명령줄 도구

http://aws.amazon.com/ko/cli/

$ sudo pip install awscli

Downloading/unpacking awscli

Downloading awscli-1.5.4.tar.gz (253kB): 253kB downloaded

Running setup.py (path:/private/tmp/pip_build_root/awscli/setup.py) egg_info for package awscli

..

.

Successfully installed awscli botocore bcdoc colorama docutils rsa jmespath pyasn1

Cleaning up...

$

$ aws configure

AWS Access Key ID [None]: XXXXXXXXXXXXXXXXX

AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Default region name [None]: ap-northeast-1

Default output format [None]: json

$

Page 6: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

$ aws s3 ls s3://yz-ngs-outputs

PRE Redis-snapshots/

PRE hohoho/

PRE pig-apache/

PRE transfer-test/

PRE wordcount/

2013-06-07 17:56:52 6097048 Elastic Beanstalk for Startups.pptx

2013-05-31 13:33:49 0 HG00099.mapped.SOLID.bfast.GBR.exome.20111114.bam

2013-05-06 15:56:56 132644272 TrendMicro-TTi_6.0_HE_Full.exe

2013-11-10 03:16:23 5188 fabricrc.txt

$

AWS 명령줄 도구

Page 7: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

http://docs.aws.amazon.com/mobile/sdkforunity/developerguide/

Page 8: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

ICE BREAKING

Page 9: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Ice breaking

“대체 무엇을 어떻게 분석해야 하는지 모르겠어요…” http://cfile1.uf.tistory.com/image/16172A3C507616AF322729

Page 10: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

분석이 없는 오늘, 현재

기획 : “아이템 드랍률을 조정하면 어떻게 될까?”

개발 : “사실… 어젯밤에 잠수함 패치 했어요.”

운영 : “게시판에 난리 났는데 대체 무슨일이에요?”

Page 11: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

게임 데이터의 분석 적용 대화의 예

기획 : “아이템 드랍률을 조정하면 어떻게 될까?”

BI팀 : “레벨 1~10까지 올리는데 12시간인데 1%드랍률 상승에 1시간 줄어

듭니다. ”

개발 : “+2% 반영 했습니다.”

BI팀 : “해당 아이템 분포는 1~10 레벨에서 15%~17% 유지중이고 반영 후

게임 내 골드 소비가 3% 줄어들었습니다.”

기획 : “그럼 다음엔…”

역시

데이터다!

Page 12: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Data-driven

데이터 기반 의사결정

고객이 누구인가

고객은 주로 어떤 캐릭터를 선택하는가

고객은 언제 게임에 돈을 쓰는가

게임이 디자인한 의도대로 플레이 되고

있는가

레벨의 분포와 게임내 에코 시스템의 상관

관계는 어떠한가

동시접속자 수 대비 DB의 TPS/QPS 는

Page 13: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

실험과 그 결과에 대한 분석 가속화

아이디어

(가설)

개발

배포

분석

사이클이 빠를 수록 게임은 사용자가 원하는 방향으로 발전

데이터 기반

의사 결정

Page 14: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

하지만 현재는…

아이디어

(가설)

개발

배포

감으로

느낌으로

Page 15: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

그렇다면 무엇을 분석 해야

레벨 분포

레벨 업그레이드 소요 시간

아이템 / 캐릭터 밸런스

캐릭터 이동 경로

로그인 / 로그 아웃 시간

etc

http://m.gameabout.com/news/view.ga?news_id=383&site=lineage&listpage=333

Page 16: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

고객에 대한 분석

“KNOW YOUR CUSTOMER”

-남성인가 여성인가

-주로 플레이하는 연령대의 분포는 어떻게 되는가

-연령대 별로 지출하는 비용의 분포는 어떠한가

-비용을 가장 많이 사용하는 게임내 요소는 무엇인가

-초/중학생을 대상으로 했는데 왜 20대 여성이 좋아하는가

http://www.clixmarketing.com/blog/2014/05/05/know-your-customers-or-else/

Page 17: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

게임 디자인에 대한 분석

의도한 바 대로 플레이 되고 있는가

“캐릭터가 건물에 갇혀서 움직이지 않아요”

“레벨 5에서 다섯시간째 삽질중”

“대체 이놈의 몹은 어디 있는거야”

“퀘스트 완료를 어느 NPC에서 해야함?”

http://sstorm.egloos.com/v/4895960

Page 18: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

매출과의 상관 관계

사장님께서 알고 싶으시단다

“비오는날 우리 매출이 어떻게 되지?”

“이번 SNS 마케팅 ROI는 어떤가?”

“어제 뉴스에 우리 게임이 나왔다던데”

http://www.gamasutra.com/view/news/197340/Clash_of_Clans_big_Japanese_boost__in_graphs.php

Page 19: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

이 모든 분석의 목적은

게임 수명의 연장

비용 효율적인 예산의 운영

보다 정확한 대상을 고려한 이벤트

고객이 더 재미를 느끼는 게임

무엇보다, “매출과 순 이익의 증가”

http://www.tutor2u.net/business/gcse/marketing-plc.gif

Page 20: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

어떻게?

Batch EMR

Page 21: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

어떻게?

Stream

Page 22: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

어떻게?

Batch Stream

Micro-Batch

Page 23: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Tuple

{…}

• 최소 데이터 단위

• 변하지 않는 원시 데이터

• 보통은 로그

{19}

Page 24: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Stream

{…} {…} {…} {…} {…}

시간의 흐름에 따라 연속된 Tuple

SEQ #1 SEQ #2 SEQ #3 SEQ #4 SEQ #5

{23} {32} {43}

Page 25: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Stream data 는

서로 다른 log 생성 디바이스

동시 접속자 수에 따른 엄청난 양의 log 데이터

실시간으로 생성되는 데이터의 분석

대규모의 원시 데이터 저장소가 필요

실시간 분석 이후에도 BI 에 대한 요구가 발생

Page 27: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Amazon Kinesis

Page 28: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

DEMO

Page 29: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

초당 수천만건의 레코드

수십만개의 데이터 소스

시간당 테라바이트의 데이터

매일 100개 이상의 ETL job

시간당 100건 이상의 SQL query

• 실시간 알람이 요구 • 스케일 가능한 구조로 변경

Kinesis

Kinesis 사용 예

Page 30: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Amazon Kinesis?

대량의 연속된 데이터를 실시간으로 처리 가능한 풀

매니지드 서비스

Kinesis는, 수십만 곳의 데이터 소스에서 테라 바이트

수준의 데이터를 처리 할 수 있으며, 저장된

데이터는 다수의 AZ에 저장하여 신뢰성과 높은

내구성을 보유한 서비스

Page 31: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis 요약

AWS SDK

LOG4J

Flume

Fluentd

Get* APIs

Kinesis Client Library + Connector Library

Apache Storm

Amazon Elastic MapReduce

PUT GET + Processing

Page 32: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis 내부 구조 및 용어

• 데이터 용도 별 Stream을 생성, Stream은 1개 이상의 Shard로 구성됨

• Shard는 데이터 입력측에서 1MB/sec, 데이터 처리측에서는 2 MB/sec 처리량을 가짐

• 입력 데이터를 Data Record라 하며, 입력 된 Data Record는 24시간 동안 다수의 AZ에 저장

• Shard의 증가 및 축소에 따라 스케일 아웃-인이 가능

Data Sources

App.4

[Machine Learning]

App.1

[Aggregate & De-

Duplicate]

Data Sources

Data Sources

Data Sources

App.2

[Metric Extraction]

S3

DynamoDB

Redshift

App.3

[Real-time Dashboard]

Data Sources

Availability Zone

Shard 1

Shard 2

Shard N

Availability Zone

Availability Zone

Kinesis

AW

S E

nd

poin

t

Stream

Page 33: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Management Console/API

Stream 이름과 Shard의 수량을 입력 Stream을 생성

용량 및 대기 시간을 모니터링, Cloud Watch모니터링 가능

Page 34: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

가격

과금

Shard 요금 $0.015/shard/시간

Put request $0.028/1,000,000PUT

예를 들어 1개월 (30일), 10Shard, 월 100,000,000PUT, 약 $110/월

Page 35: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

데이터 입력

AWS SDK

LOG4J

Flume

Fluentd

Get* APIs

Kinesis Client Library + Connector Library

Apache Storm

Amazon Elastic MapReduce

PUT GET + Processing

Page 36: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

데이터 입력 방법

PutRecord API 로 데이터 입력이 가능 http://docs.aws.amazon.com/kinesis/latest/APIReference/API_PutRecord.html

AWS SDK for Java, Javascript, Python, Ruby, PHP, .Net 예)boto를 이용하여 put_record

http://docs.pythonboto.org/en/latest/ref/kinesis.html#module-boto.kinesis.layer1

Page 37: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Stream

Shard-0

Shard-1

Data Record

Data Record

Data Record

Kinesis는 받은 데이터를 Shard 에 분배

Page 38: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Data Record에 설정된 파티션 키를 기준으로 Shard에 분배

Stream

Shard-0

Shard-1

Data Record

Data Record

Data Record

DataRecord의 내용

데이터 (Max 50KB)

파티션 키 (Max 256B)

Page 39: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Shard는 각 담당하는 범위를 기준으로 파티션 키와 MD5 값이 일치하는 범위의 Shard 에 분배

예 0

MD5의 범위

2128

Shard-1 (2128/2 - 2128)

MD5(파티션 키)

Shard-0 (0 - 2128/2)

데이터 파티션 키

값은 둘중 하나에 분배

Page 40: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

TIPS

Shard는 Partition Key를 기반으로 분배 Shard의 용량은

Partition key 를 잘 설계하여 좋은 분산을 구현할 필요가 있다

Page 41: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Shard

시퀀스 넘버

Stream에 입력된 Data Record에 Kinesis의 Stream에서 유니크한 시퀀스 번호를 부여 (시간경과에 따라 함께 증가하는 구조) 연속된 PutRecord API를 호출하는 경우 순서가 달라질 수 있다. 동일한 파티션 키에서 순서가 매우 중요한 경우, PutRecord API의 호출에 주의 SequenceNumberForOrdering 매개 변수를 설정한다 시퀀스 번호는 PutRecord API 응답으로 확인 가능

데이터 레코드 (14)

데이터 레코드 (15)

데이터 레코드 (17)

데이터 레코드 (19)

데이터 레코드 (20)

Page 43: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

데이터 수집 및 처리

AWS SDK

LOG4J

Flume

Fluentd

Get* APIs

Kinesis Client Library + Connector Library

Apache Storm

Amazon Elastic MapReduce

PUT GET + Processing

Page 44: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

데이터 수집

GetShardIterator API에서 Shard의 위치를 검색, GetRecords API를

사용하여 Kinesis 에 저장된 데이터를 가져올 수 있음 http://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetShardIterator.html

http://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetRecords.html

AWS SDK for Java, Javascript, Python, Ruby, PHP, .Net

예)boto를 사용하여 get_shard_iterator, get_records

http://docs.pythonboto.org/en/latest/ref/kinesis.html#module-boto.kinesis.layer1

Page 45: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

GetShardIterator의 검색 지정 방법

GetShardIterator API는 ShardIteratorType을 지정하고 포지션을 얻을 수 있음

ShardIteratorType 은 다음과 같음 AT_SEQUENCE_NUMBER ( 지정된 시퀀스 넘버에서 데이터를 가져옴 )

AFTER_SEQUENCE_NUMBER ( 지정된 시퀀스 넘버 이후부터 데이터를 가져옴 )

TRIM_HORIZON ( Shard에 존재하는 가장 오래된 데이터부터 가져옴 )

LATEST ( 최신 데이터부터 가져옴 )

Seq: xxx

LATEST

AT_SEQUENCE_NUMBER AFTER_SEQUENCE_NUMBER

TRIM_HORIZON

GetShardIterator의 동작

Page 46: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis Client Library

• GetShardIterator API 및 GetRecords API를 이용하여 데이터의 검색 및 데이터 처리를 할 수 있지만, 데이터를 처리하는 인스턴스에 대한 고가용성과 Shard 의 분할, 병합등의 복잡한 처리를 구현할 필요가 있다.

• Kinesis Client Library를 이용하면 이러한 복잡한 과정을 따로 구현하지 않고 비지니스 로직에 집중 할 수 있다.

• Kinesis Client Library는 Java 를 지원

• Github에서 소스를 확인 할 수 있음 – https://github.com/awslabs/amazon-kinesis-client

• Kinesis Client Library는 체크 포인트의 관리에 DynamoDB를 이용하고 있으며 처음 시작할때 DynamoDB 테이블을 생성한다.

– 기본적으로 Read Provisioned Throughput, Write Provisioned Throughput은 10으로 설정됨

Page 47: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis Client Library

• Kinesis Client Library를 사용한 응용 프로그램(Kinesis응용 프로그램)을 실행하면 Worker 가 생성되어 Kinesis 에서 데이터를 검색한다.

• Kinesis 응용 프로그램 측면에서는 구성 설정 및 데이터 처리를 위한 IRecordProcessor 를 사용

• 개발 관련 내용은 다음의 링크를 참조 – http://docs.aws.amazon.com/kinesis/latest/dev/kinesis-record-processor-

app.html

Page 48: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis Client Library 샘플 코드

public class SampleRecordProcessor implements IRecordProcessor { @Override public void initialize(String shardId) { LOG.info("Initializing record processor for shard: " + shardId); this.kinesisShardId = shardId; } @Override public void processRecords(List<Record> records, IRecordProcessorCheckpointer checkpointer) { LOG.info("Processing " + records.size() + " records for kinesisShardId " + kinesisShardId); // Process records and perform all exception handling. processRecordsWithRetries(records); // Checkpoint once every checkpoint interval. if (System.currentTimeMillis() > nextCheckpointTimeInMillis) { checkpoint(checkpointer); nextCheckpointTimeInMillis = System.currentTimeMillis() + CHECKPOINT_INTERVAL_MILLIS;

} } }

[Sample RecordProcessor ]

Page 49: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis Client Library 샘플 코드

IRecordProcessorFactory recordProcessorFactory = new SampleRecordProcessorFactory(); Worker worker = new Worker(recordProcessorFactory, kinesisClientLibConfiguration); int exitCode = 0; try { worker.run(); } catch (Throwable t) {

LOG.error("Caught throwable while processing data.", t); exitCode = 1; }

[Sample Worker]

Page 50: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Stream

Shard-0

Shard-1

Kinesis 응용 프로그램

(KCL) 작업 인스턴스

시퀀스 넘버

Instance A 12345

Instance B 98765

Data Record (12345)

Data Record (24680)

Data Record (98765)

DynamoDB

Instance A

Kinesis 응용 프로그램

(KCL)

Instance B

1. Kinesis Client Library가 Shard로 부터 Data Record를 Get 2. 설정된 간격으로 일련 번호를 인스턴스의 ID를 키로 사용하여 DynamoDB의

테이블에 저장

(*)실제 Key, Attribute 이름은 동일하지 않음

Page 51: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Stream

Shard-0

Kinesis 응용 프로그램

(KCL) 작업 인스턴스

시퀀스 넘버

Instance A → Instance B

12345 Data Record (12345)

Data Record (24680)

DynamoDB

Instance A

Kinesis 응용 프로그램

(KCL)

Instance B

Instance A가 동작하지 않는 상황을 감지, Instance B가 DynamoDB에 저장된 시퀀스 번호 부터 데이터 Get

Page 52: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Stream

Shard-0

Kinesis 응용 프로그램

(KCL)

Shard 작업 인스턴스

시퀀스 넘버

Shard-0

Instance A

12345

Shard-1

Instance A

98765

Data Record (12345)

Data Record (24680)

DynamoDB

Instance A

Shard-1 이 증설된 것을 감지하여 데이터 수집을 시작하고 Shard-1 의 체크포인트 정보를 DynamoDB 에 추가

Shard-1

Data Record (98765)

New

Page 53: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Stream

シャード

Shard

データ レコード (12345)

データ レコード (98765)

データ レコード (24680)

데이터 레코드 (12345)

데이터 레코드 (98765)

데이터 레코드 (24680)

응용 프로그램 (KCL)

Instance A Shard 작업 인스턴스

시퀀스 넘버

Shard-0

Instance A

12345

Shard-1

Instance A

98765

응용 프로그램 (KCL)

Instance A Shard 작업 인스턴스

시퀀스 넘버

Shard-0

Instance A

24680

Shard-1

Instance A

98765

각 응용 프로그램마다 서로 다른 테이블에서 관리

Archive Table

Calc Table

Page 54: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis Connector Library

Kinesis Connector Library를 이용하면 S3, DynamoDB、Redshift와 같은 다른 서비스와

연동이 매우 용이함

Kinesis Connector Library는 Java를 지원

Github 링크 https://github.com/awslabs/amazon-kinesis-connectors

RedShift

DynamoDB

S3

다른 데이터 분석을 위해 저장

실시간 대시 보드 및 순위

축적된 데이터를 다각도로 분석

Kinesis

Page 55: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Data Record의 검색, 변환, 필터, 버퍼 및 저장등을 매우 쉽게 구현 가능

ITransformer

•Kinesis

에서

사용자가

원하는

모델로

변환

IFilter

•데이터를

필터링,

필터링을 거친

데이터가

버퍼로 이동

IBuffer

•지정된

레코드 또는

바이트까지

버퍼

IEmitter

•다른 AWS

서비스

접근

S3

DynamoDB

Redshift

Kinesis

Kinesis Connector Library

Page 56: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis Connector Library 샘플 코드

public class S3Pipeline implements IKinesisConnectorPipeline<KinesisMessageModel, byte[]> { @Override public ITransformer<KinesisMessageModel, byte[]> getTransformer(KinesisConnectorConfiguration configuration) { return new JsonToByteArrayTransformer<KinesisMessageModel>(KinesisMessageModel.class); } @Override public IFilter<KinesisMessageModel> getFilter(KinesisConnectorConfiguration configuration) { return new AllPassFilter<KinesisMessageModel>(); } @Override public IBuffer<KinesisMessageModel> getBuffer(KinesisConnectorConfiguration configuration) { return new BasicMemoryBuffer<KinesisMessageModel>(configuration); } @Override public IEmitter<byte[]> getEmitter(KinesisConnectorConfiguration configuration) { return new S3Emitter(configuration); } }

[Sample S3 pipeline]

JSON을 ByteArray로 변환

패스 필터

메모리 버퍼

S3에 데이터 저장

Page 57: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis Storm Spout • Kinesis에서 Apache Storm의 통합을 용이하게 하기 위한 Spout

• Kinesis Storm Spout은 Java 를 지원

• Github

– https://github.com/awslabs/kinesis-storm-spout

Page 58: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

EMR Connector

• Hive、Pig、Cascading、Hadoop Streaming등 친숙한 Hadoop 관련 도구를 사용하여 Kinesis Stream의 데이터를 검색, Map Reduce 처리가 가능

• ETL 처리와 다른 Kinesis Stream, S3, DynamoDB, HDFS의 Hive Table등의 다른 데이터 소스의 테이블과 JOIN 하는것도 가능

– (예) Clickstream (Kinesis) JOIN Ad campaign data (DynamoDB)

Kinesis Stream EMR Hive

Table

Data Storage

Table Mapping

(Hive 사용의 경우)

http://docs.aws.amazon.com/ElasticMapReduce/latest/DeveloperGuide/emr-kinesis.html

Page 59: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

EMR Connector : Hive 사용 사례

Hive 테이블 생성

Kinesis Stream 정의

HQL 실행 (예)

HQL을 실행하면 내부적으로는 Kinesis 에서 데이터를 검색, 처리

Page 60: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

• 먼저 처리된 데이터의 중복 처리를 피하기 위해 DynamoDB 를 사용하여 체크포인트를 참조

• Data pipeline / Crontab 을 주기적으로 실행하여 Kinesis에서 주기적으로 데이터를 수신, 처리가 가능

EMR Connector : Hive 사용 사례

Page 61: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis의 운용

Page 62: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

CloudWatch를 통한 모니터링

메트릭

GetRecords.Bytes GetRecords 로 얻은 바이트 수

GetRecords.IteratorAge GetShardIterator 사용 시간

GetRecords.Latency GetRecords 지연시간

GetRecords.Success GetRecords API 정상 처리 카운트

PutRecord.Bytes PutRecord 로 입력된 바이트 수

PutRecord.Latency PutRecord 지연시간

PutRecord.Success PutRecord API 정상 처리 카운트

Page 63: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Shard의 분산 및 병합

Shard의 용량과 실제 사용에 따라 Shard 를 분할 또는 병합하여

처리량의 확장과 비용의 최적화가 가능

SpritShard API로 분할, MergeShards API로 병합 가능 (SpritShard) http://docs.aws.amazon.com/kinesis/latest/APIReference/API_SplitShard.html

(MergeShards) http://docs.aws.amazon.com/kinesis/latest/APIReference/API_MergeShards.html

AW

S En

dp

oin

t

Availability

Zone

Shard 1

Shard 2

Shard N

Availability

Zone Availability

Zone Shard-

1

Shard-

2

Shard-

1

Shard-

2

Shard-

3

Shard-

4 분할

Page 64: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

SpritShard와 MergeShards의 적용예

처리하고자 하는 데이터의 특성에 맞게 Shard를 운용 Shard는 시간단위로 비용이 청구되므로 낭비 없이 사용 할 수 있도록 Split /Merge 를 적용

처리량이 많아지는 시간에 Shard 를 분할하고 적어지면 병합하는 방법

Page 65: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

SpritShard API

SpritShard에서 담당하는 Hash key 의 시작값을 지정

conn = KinesisConnection()

descStream = conn.describe_stream(stream_name)

for shard in descStream['StreamDescription']['Shards']:

StartHashKey = shard['HashKeyRange']['StartingHashKey']

EndHashKey = shard['HashKeyRange']['EndingHashKey’]

NewHashKey = (long(EndHashKey) - long(StartHashKey))/2

print "StartHashKey : ", StartHashKey

print "EndHashKey : ", EndHashKey

print "NewHashKey : ", str(NewHashKey)

ret = conn.split_shard(stream_name,targetShard,str(NewHashKey))

Boto를 사용한 예:1Stream1Shard를 절반으로 분할

StartHashKey : 0

EndHashKey : 340282366920938463463374607431768211455

NewHashKey : 170141183460469231731687303715884105727

위의 코드로 출력되는 내용: 0-34의 shard가 0-17xx , 17xx-34xx 로 분할 )

Page 66: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

MergeShards API

MergeShards API는 기존 Shard 와 병합하려는 Shard 를 지정

conn = KinesisConnection()

conn.merge_shards(stream_name,targetShard, mergedShard)

Boto 사용 예

Page 67: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Digital Ad. Tech Metering with Kinesis

Incremental Ad.

Statistics

Computation

Metering Record Archive

Ad Analytics Dashboard

Continuous

Ad Metrics

Extraction

Page 68: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Stream을 연속으로 연결

Data Sources

Data Sources

Data Sources

Kinesis App

Kinesis App

Kinesis App

Data Sources

Data Sources

Data Sources

Kinesis App

Kinesis App

Kinesis App

Kinesis App

Data Source 그룹 A

Data Source 그룹 B

Data Source 그룹A용 ETL (클렌징)

Data Source 그룹B용 ETL (클렌징)

집계

Page 69: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

다른 AWS 서비스와 연동

AW

S E

ndpoin

t

Kinesis App.1

Kinesis App.2

Redshift

DynamoDB

Kinesis App.3

Availability Zone

Shard 1

Shard 2

Shard N

Availability

Zone

Availability

Zone

RDS

데이터 분석가

BI도구, 통계 분석

Data as a Service를 제공

서비스 제공

S3

기업 데이터의 저장

최종 사용자에게 push

Kinesis에 의한 스트림 저장

Page 70: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

SQS와 Kinesis의 구분 Kinesis는 Pub-Sub 메세지 모델을 구축 가능하며, Stream에서

유일한 시퀀스 넘버가 DataRecord에 부여되기 때문에 순차적인

처리가 가능하다

SQS

데이터 소스 Worker

Worker

단일 메세지 타입에 대해 여러 Worker 가 처리

Kinesis

데이터소스 Worker

A

Worker B

목적에 따라 Kinesis 응용 프로그램을 구현하여 동일한 소스 데이터를 동시에 사용 가능

Page 71: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

실시간 대시 보드 Web로그, 센서 데이터 등 실시간 정보의 시각화 용도

단기적인 데이터의 시각화 뿐만 아니라 장기적인 분석을 위한 저장도

가능

센서

센서

센서 Kinesis App [보관]

Dashboard Kinesis App [요약, 이상 감지]

Redshift

DynamoDB

Page 73: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

ETL

수집된 데이터의 사전 처리용도로 이용

로그

로그

로그

Kinesis App [ETL처리]

S3 EMR

Page 74: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

버퍼

대량 데이터의 기본 버퍼로 사용

SQS에서도 같은 구성이 가능

Worker 부분에 Storm을 배포하는 조합도 가능

Data Sources

Data Sources

Data Sources

Kinesis App [Worker]

Kinesis App [Worker]

Page 75: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

쉬운 관리

실시간 스트리밍 데이터 수집

및 처리를 위한 매니지드

서비스. Stream 구축이 매우

쉬움

실시간

스트리밍 유형의 빅데이터

처리가 가능. 몇분, 몇시간의

배치성 처리와 비교하여 몇초

이내로 데이터 처리가 가능

신축성

처리 속도와 볼륨을 원하는

대로 변경 가능하여 비지니스

요구에 맞는 스케일 업/다운이

가능

S3, Redshift, &

DynamoDB

통합

데이터의 수집, 변환, 처리 후

S3및 Redshift, DynamoDB에

저장하는것이 가능

실시간 처리

응용 프로그램

Kinesis Client Library를

이용하여 쉽게 실시간

스트리밍 데이터 처리의

구현이 가능

Low Cost

모든 규모의 워크로드를 비용

효율적으로 수용 가능

Amazon Kinesis

Page 77: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Amazon EMR

What is EMR?

Map-Reduce 엔진 다양한 도구와 연동 가능

하둡 서비스

대규모 병렬 처리

비용 효율적인 Wrapper

다양한 AWS 서비스 연동

Page 78: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

EMR 의 확장

HDFS

EMR

Page 79: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

다른 AWS 서비스 연동

HDFS

EMR

S3 DynamoDB

Page 80: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Hbase, Flume 연동

HDFS

EMR

S3 DynamoDB

Data management

Page 81: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Hive, Pig script

HDFS

EMR

Pig

S3 DynamoDB

Analytics languages Data management

Page 82: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Sqoop 연동

HDFS

EMR

Pig

S3 DynamoDB

RDS

Analytics languages Data management

RedShift

AWS DataPipeline

Page 83: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

EMR bootstrap

• R

• Elasticsearch

• Ganglia

• Hbase

• Presto

• Spark

• Spark_shark

• Etc.

https://github.com/awslabs/emr-bootstrap-actions

Page 84: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis + Spark on EMR

• Apache Spark on EMR • 실시간에 가까운 ETL 구현이 가능 • 아래의 블로그에서 내용의 확인이 가능

https://aws.amazon.com/articles/Elastic-MapReduce/4926593393724923

EMR Cluster Kinesis

Page 85: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis + Storm on EMR

• Apache Storm • Github

https://github.com/awslabs/kinesis-storm-spout

Data Sources

Data Sources

Data Sources

Storm Spout

Storm Bolt

Storm Bolt

Storm Bolt

Page 86: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Kinesis + Machine learning on EMR

Data Sources

Data Sources

Data Sources

Machine Learning Jubatus

Archive

Notify

Training data

Ex: Online Machine Learning Integration (Jubatus)

Feedback

Page 88: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

“데이터만 있으면 쿼리 날리는게 제일 편하죠!”

“그런데 DW 는 비싸잖아요… ㅠㅠ”

Amazon Redshift 병렬 처리가 가능한 데이터 웨어하우징 서비스

Page 89: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Data Warehouse as a Service – 분석을 위한 대량의 데이터를 저장,

쿼리가 가능한 데이터 베이스 서비스

확장성:수TB ~수PB

성능:컬럼 기반 저장, 대규모 병렬 처리(MPP)

비용:인스턴스를 사용한 만큼만 과금(초기 투자 비용, 라이센스 비용

필요없음)

특장점

Page 90: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Row 기반 vs. Column 기반

DWH 에는 컬럼 기반의 데이터베이스가 주로 사용된다

orderid name qty

1 Book 100

2 Pen 50

n Eraser 70

orderid name qty

1 Book 100

2 Pen 50

n Eraser 70

Row 기반 – 트랜젝션 처리에 유리 Column 기반 – 분석 처리 방향

Page 91: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

내부 아키텍처

마스터 노드를 통해 쿼리를 수용, 각

노드에 수행할 쿼리를 전달

각 컴퓨팅 노드에서 쿼리를 병렬 실행

각 컴퓨팅 노드의 로컬 스토리지에 데이터를 유지

4개의 타입의 컴퓨팅 노드를 선택 가능

BI 도구

마스터 노드

컴퓨팅 노드

컴퓨팅 노드

컴퓨팅 노드

JDBC/ODBC

10GigE Mesh

SQL Endpoint: •쿼리를 병렬처리 •결과를 취합

실제 쿼리 수행 노드 •“N” 스케일 아웃 •로컬 디스크의 사용

Page 92: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

클러스터의 확장성 (dw1)

단일 노드 (2TB)

클러스터 2 ~ 32 노드 (4TB – 64TB)

클러스터 2 ~ 100 노드 (32TB – 1.6PB)

Extra Large Node (XL)

8 Extra Large Node (8XL)

Page 93: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

단일 노드 (160GB)

클러스터 2 ~ 32 노드 (320GB – 5.12TB)

클러스터 2 ~ 100 노드 (5.12TB – 256TB)

Large Node (XL)

8 Extra Large Node (8XL)

클러스터의 확장성 (dw2)

Page 94: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

테이블 디자인

- 최적의 SORTKEY 선택이 필요

SORTKEY 에 따라 데이터를 디스크에 순차적으로 저장

쿼리 옵티마이저는 SORTKEY 에 따라 실행계획을 구축

- 최적의 DISTKEY 선택

DISTKEY 는 컴퓨팅 노드간의 데이터 배치를 결정하는데 사용

- 최적의 압축 유형 선택

다수의 압축 알고리즘에서 선택 가능

- 제약 조건의 정의

기본키 제약 조건과 외래키 제약 조건은 실행계획을 만들때

팁으로 사용됨

Page 95: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

SORTKEY 선택 - SORTKEY

SORTKEY 에 따라 디스크에 데이터를 순차적으로 저장

쿼리 옵티마이저는 정렬 순서를 고려하여 최적의 쿼리 실행

계획을 구축

- Tips

특정 컬럼에 대해 잦은 범위 검색 또는 등식 검색이 필요한 경우

SORTKEY 로 지정

-> 검색되지 않는 블록에 대한 접근을 생략하여 높은 성능을 유지

자주 조인하는 경우 해당 컬럼을 SORTKEY 및 DISTKEY 로

지정

-> 해시 조인 대신 정렬 병합 조인이 선택됨

Page 96: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

SORKEY 예제

Orderdate 컬럼을 SORTKEY 로 지정한 경우:

2013/07/17

2013/07/18

2013/07/18

2003/07/19

I0001

I0002

I0003

I0004

・・・

2013/08/20

2013/08/21

2013/08/22

2013/08/22

I0020

I0021

I0022

I0023

orderdate … orderid

SELECT * FROM orders WHERE

orderdate BETWEEN ‘2013-08-01’ AND

‘2013-08-31’;

쿼리와 관련이 없는 데이터 블록은

건너뛰고 해당 블록만 참조

SORKEY 예제

Page 97: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

DISTKEY 선택 - DISTKEY

DISTKEY 는 테이블의 데이터가 어떻게 분산되어 저장될지를

결정

지향해야 할 목표

노드 슬라이스간에 최대한 데이터를 고르게 분산 해야 함

-> 편향된 데이터의 저장은 특정 노드의 부하를 증가시켜 전체

처리성능을 지연시킬 가능성이 있음

조인이 필요한 경우 컴퓨트 노드간 데이터의 전송을 최소화

하기 위한 데이터 배열을 염두

- 분산 방식: CREATE TABLE ~ DISTSTYLE EVEN | KEY

Even distribution:라운드 로빈의 형태로 데이터를 분산

Key distribution:DISTKEY 에 따라 데이터를 분산

http://docs.aws.amazon.com/redshift/latest/dg/t_Distributing_data.html

Page 98: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

압축 유형 선택(1)

데이터 압축을 통해 1회의 IO로 읽을 데이터의 양을 증가

Redshift는 1MB의 블록 크기를 사용함

데이터 압축시 CPU 자원을 사용

「analyze compression」커맨드는 최적의 압축 알고리즘을 제시해 줌

analyze compression listing;

Table | Column | Encoding

---------+----------------+----------

listing | listid | delta

listing | sellerid | delta32k

listing | eventid | delta32k

listing | dateid | bytedict

listing | numtickets | bytedict

listing | priceperticket | delta32k

listing | totalprice | mostly32

listing | listtime | raw

Page 99: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

압축 유형 선택(2)

데이터 압축 알고리즘

- RAW:압축하지 않음

- BYTEDICT:CHAR 와 같이 고정된 크기 제한을 가지는 컬럼에 적합

- DELTA/DELTA32K:연속되는 값을 최적화(datetimes、sequence 등)

- LZO : JSON string 을 가지는 VARCHAR, CHAR 와 같이 많은 데이터를 가지는

컬럼에 유용. 높은 압축률을 자랑

- MOSTLY8、MOSTLY16、MOSTLY32:대부분의 값이 낮은 범위의 비트 숫자에

집중되는 경우 최적화

- RUNLENGTH:동일한 값이 자주 연속되는 경우 최적화

- TEXT255/TEXT32K:텍스트 내의 단어 사전을 이용

http://docs.aws.amazon.com/redshift/latest/dg/c_Compression_encodings.html

Page 100: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

데이터 압축의 예

Orderdate 컬럼에 DELTA 인코딩을 적용:

2013/08/20

2013/08/21

2013/08/22

2013/08/22

I0020

I0021

I0022

I0023

orderdate … orderid

2013/08/20

1

1

0

I0020

I0021

I0022

I0023

레코드가 저장될때 4바이트 DATE 형태로 저장되는 것이 아니라 이전 레코드와 차이를 나타내는 숫자로 저장된다.

주의: 이 내용은 개념을 설명하기 위한 것이며, 실제 사용시에는 테이블 생성 이후 인코딩의 변경은 불가능

Page 101: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

제약 조건의 정의

기본키와 외래키 제약 조건은 어디까지나 정보로만 간주됨

쿼리 플래너가 실행 계획을 만들때 힌트로 사용

주의 사항

플래너는 제약 조건이 정의 되어있는 경우 항상 데이터가 타당하다고

인식 (예: 고유 및 외래키로 참조 가능)

일관성이 없는 데이터는 잘못된 쿼리 결과를 출력할 수도 있다

데이터의 유효성이 확실한 경우에만 제약 조건을 정의

Page 102: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

데이터의 로딩

AWS 의 다양한 서비스에서 데이터의 로딩이 가능 Amazon S3 에서 각 노드에 병렬로 데이터를 로드 Amazon DynamoDB 테이블의 데이터를 로드 Amazon EMR (예정) 데이터 로드시 발생한 오류를 추적 가능

스타 스키마, 인덱스는 필요하지 않음 RDBMS와 비교하여 x 2 – 4 배의 압축

다양한 압축 알고리즘을 채용 자동 압축 가능

Page 103: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

데이터의 로딩

Amazon S3 에 저장된 데이터를 COPY 를 사용하여 로딩

% psql --host=mydb.wetyuioop.us-east-1.redshift-

dev.amazonaws.com --port=5439 –username=admin --

dbname=mydb

mydb=# copy customer from 's3://data/customer.tbl.1'

credentials

'aws_access_key_id=XXXXYYYYZZZZ;aws_secret_acc

ess_key=abcdefghijklmn' delimiter '|';

Page 104: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

성능 조정시 고려사항

성능을 확인하는 방법

EXPLAIN 명령의 사용, SVL_QUERY_SUMMARY,

SVL_QUERY_REPORT 테이블 참조

쿼리 실행 계획의 분석, 필요에 따라 쿼리를 수정

얼마나 많은 자원을 소비하는지 확인하는 방법

쿼리 수행시 결과를 출력하기 위해 사용되는 I/O 모니터링

메모리 소비량을 분석

스키마의 재설계, SORTKEY 와 DISTKEY

쿼리가 다른 쿼리의 완료를 대기하고 있는지의 여부

각 쿼리의 실행 시간을 파악하고 우선 순위를 결정

다수의 대기열을 정의하고 여기에 쿼리를 입력

Page 105: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

쿼리의 분석(1)

EXPLAIN 커맨드

EXPLAIN 을 통해 확인 할 수 있는 내용:

쿼리의 실행 단계

각 단계에서 어떠한 작업이 수행되는지

각 단계에서 어떤 테이블, 컬럼이 사용되는지

각 단계에서 얼마나 많은 데이터를 처리할 필요가 있는지

105

explain select avg(datediff(day, listtime, saletime)) as avgwait from sales, listing

where sales.listid = listing.listid;

QUERY PLAN

XN Aggregate (cost=6350.30..6350.31 rows=1 width=16)

-> XN Hash Join DS_DIST_NONE (cost=47.08..6340.89 rows=3766 width=16)

Hash Cond: ("outer".listid = "inner".listid)

-> XN Seq Scan on listing (cost=0.00..1924.97 rows=192497 width=12)

-> XN Hash (cost=37.66..37.66 rows=3766 width=12)

-> XN Seq Scan on sales (cost=0.00..37.66 rows=3766 width=12)

http://docs.aws.amazon.com/redshift/latest/dg/c-optimizing-query-performance.html

Page 106: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

쿼리의 분석 (2)

대량의 데이터를 업데이트 한 경우에는 ANALYZE 를 사용하여 통계를 갱신.

쿼리의 실행 계획이 변경될 수도 있음

STL_EXPLAIN 테이블 참조 (이전에 실행된 쿼리 분석)

SVL_QUERY_SUMMARY 와 SVL_QUERY_REPORT 에 더 자세한 정보가

포함되어 있으므로 참조

106

analyze lineitem;

select query,nodeid,parentid,substring(plannode from 1 for 30),

substring(info from 1 for 20) from stl_explain

where query=10 order by 1,2;

query | nodeid | parentid | substring | substring

------+--------+----------+---------------------+---------------------

10 | 1 | 0 | XN Aggregate (cost=6350.30... |

10 | 2 | 1 | -> XN Merge Join DS_DIST_NO | Merge Cond: ("outer"

10 | 3 | 2 | -> XN Seq Scan on lis |

10 | 4 | 2 | -> XN Seq Scan on sal |

Page 107: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

쿼리의 분석(3)

Management Console 에서 확인

각 쿼리의 내용 및 부하정도를 확인 가능

Page 108: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

Amazon Redshift 의 장점

DW를 위한 초기 비용이 필요하지 않음

DWH에 필요한 Disk 를 할당하고 사용한 만큼만 과금

확장성

필요할때 노드를 추가함으로서 데이터 저장공간의 확장이 매우 쉽다

운영과 관리가 매우 편리

Management Console 에서 클러스터의 생성, 크기 조정, 복원 및 백업이

모두 가능

Page 109: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

정리

데이터 생성 : 게임 서버, 엔드 유저 클라이언트

데이터 수집 : Amazon Kinesis

데이터 저장 : Amazon S3

데이터 실시간 분석 : EMR Storm / Spark / Kinesis Client / Lambda

데이터 웨어 하우징 : Amazon Redshift

Page 110: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

중요한 점은

아이디어

(가설)

개발

배포

분석

• 분석은 반드시 필요

• 적절한 방법을 선택

• AWS 에서는 배치/실시간이

모두 손쉽게 가능

• 비용이 매우 저렴

Page 111: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

지금 바로 Concept 을 확인해 보세요

Game servers Kinesis stream Kinesis

Client

Log store

Log data record Get data Store

EMR Redshift

DynamoDB

Co

py

BI

Real time/

Batch

로그인 / 로그아웃 데이터 부터

Page 112: 성공적인 게임 런칭을 위한 비밀의 레시피 #3

aws.amazon.com/ko/game-hosting