SlideShare ist ein Scribd-Unternehmen logo
1 von 273
Downloaden Sie, um offline zu lesen
〈야생의 땅: 듀랑고〉의 데이터 엔지니어링 이야기
넥슨 컴퍼니 왓 스튜디오
전효준
: 로그 시스템 구축 경험 공유
2부
SlideShare에 슬라이드 300장 제한으로
부득이하게 2부로 나누어 올렸습니다.
현재 보고 계신 슬라이드는 2부입니다.
분석
마지막으로 이렇게 S3에 적재한 로그를
분석하는 단계인데요.
분석 클러스터
S3 ZeppelinSpark
AWS EMR
DataPipeline
전체적으로 Apache Spark와
Apache Zeppelin을 사용하고 있습니다.
분석 클러스터
S3 ZeppelinSpark
AWS EMR
클러스터 컴퓨팅 엔진
DataPipeline
Apache Spark는
클러스터 컴퓨팅 엔진으로
분석 클러스터
S3 ZeppelinSpark
AWS EMR
대화식 인터프리터
+ 쉬운 시각화
DataPipeline
Zeppelin은 이런 Spark를
대화식 인터프리터에서 사용하게 해주고
분석 클러스터
S3 ZeppelinSpark
AWS EMR
대화식 인터프리터
+ 쉬운 시각화
DataPipeline
결과를 시각화하는 용도로 사용하고 있고요.
분석 클러스터
S3 ZeppelinSpark
AWS EMR
클러스터 구성
DataPipeline
이러한 Spark와 Zeppelin의
클러스터를 구성하는 데에
분석 클러스터
S3 ZeppelinSpark
AWS EMR
클러스터 구성
DataPipeline
EMR이라는 서비스를 사용하고 있습니다.
분석 클러스터
S3 ZeppelinSpark
AWS EMR
DataPipeline
배치잡 구성
그리고 여기 옆에 DataPipeline은
배치잡을 구성하는 데 사용하고있습니다.
ZeppelinSpark
AWS EMR
먼저 Spark와 Zeppelin, 그리고 이것을 구성하는
EMR에 대해서 말씀드리려고 합니다.
• 클러스터 컴퓨팅 엔진
•
• Python, Scala, R, Java 언어지원
• 다양한 모듈 지원 (SparkSQL, MLlib 등)
Apache Spark
Spark
인 메모리 데이터 처리
Apache Spark는 클러스터 컴퓨팅 엔진인데요.
• 클러스터 컴퓨팅 엔진
•
• Python, Scala, R, Java 언어지원
• 다양한 모듈 지원 (SparkSQL, MLlib 등)
Apache Spark
Spark
인 메모리 데이터 처리 → 빠르다!
이전에 Hadoop에서 디스크 기반으로 수행하던
MapReduce 작업을
• 클러스터 컴퓨팅 엔진
•
• Python, Scala, R, Java 언어지원
• 다양한 모듈 지원 (SparkSQL, MLlib 등)
Apache Spark
Spark
인 메모리 데이터 처리 → 빠르다!
Spark에서는 메모리에서 처리하기 때문에
• 클러스터 컴퓨팅 엔진
•
• Python, Scala, R, Java 언어지원
• 다양한 모듈 지원 (SparkSQL, MLlib 등)
Apache Spark
Spark
인 메모리 데이터 처리 → 빠르다!
빠른 속도라는 장점을 가지고 있습니다.
• 클러스터 컴퓨팅 엔진
•
• Python, Scala, R, Java 언어지원
• 다양한 모듈 지원 (SparkSQL, MLlib 등)
Apache Spark
Spark
인 메모리 데이터 처리 → 빠르다!
다양한 언어를 지원하기도 하고
• 클러스터 컴퓨팅 엔진
•
• Python, Scala, R, Java 언어지원
• 다양한 모듈 지원 (SparkSQL, MLlib 등)
Apache Spark
Spark
인 메모리 데이터 처리 → 빠르다!
데이터에 대하여 SQL을 사용할 수 있는
SparkSQL 모듈과
• 클러스터 컴퓨팅 엔진
•
• Python, Scala, R, Java 언어지원
• 다양한 모듈 지원 (SparkSQL, MLlib 등)
Apache Spark
Spark
인 메모리 데이터 처리 → 빠르다!
머신러닝 라이브러리, 스트리밍 모듈 등
여러가지 모듈을 지원하는데
• 클러스터 컴퓨팅 엔진
•
• Python, Scala, R, Java 언어지원
• 다양한 모듈 지원 (SparkSQL, MLlib 등)
Apache Spark
Spark
인 메모리 데이터 처리 → 빠르다!
클러스터 컴퓨팅 엔진이라고 소개해 드리긴 했지만
• 클러스터 컴퓨팅 엔진
•
• Python, Scala, R, Java 언어지원
• 다양한 모듈 지원 (SparkSQL, MLlib 등)
Apache Spark
Spark
인 메모리 데이터 처리 → 빠르다!
범용 분산 플랫폼이 맞는 표현입니다.
df = spark.read.json('logs.json')
over_21 = df.where('age >= 21').count()
보고 계신 코드는 Spark에서
JSON 포맷의 로그를 읽고
df = spark.read.json('logs.json')
over_21 = df.where('age >= 21').count()
나이가 21세 이상인 사람들에 대한
로그를 카운트하는 예제입니다.
df = spark.read.json('logs.json')
over_21 = df.where('age >= 21').count()
Spark에서 저희가 주로 사용하는
데이터 프레임이라는 데이터 구조를 사용한 코드인데요.
df = spark.read.json('logs.json')
over_21 = df.where('age >= 21').count()
실제로 보시는 바와 같이 쉽게 사용할 수 있습니다.
•
• 다양한 인터프리터 사용가능
• 쉬운 시각화
Apache Zeppelin
Zeppelin
대화식 분석이 가능한 웹 기반 노트북
다음으로는 이런 Spark 사용을 쉽게해주는
Apache Zeppelin입니다.
•
• 다양한 인터프리터 사용가능
• 쉬운 시각화
Apache Zeppelin
Zeppelin
대화식 분석이 가능한 웹 기반 노트북
대화식 분석이 가능하기 때문에
•
• 다양한 인터프리터 사용가능
• 쉬운 시각화
Apache Zeppelin
Zeppelin
대화식 분석이 가능한 웹 기반 노트북
파이썬으로 데이터 분석하시는 분들께서
많이 사용하시는 Jupyter notebook 처럼
•
• 다양한 인터프리터 사용가능
• 쉬운 시각화
Apache Zeppelin
Zeppelin
대화식 분석이 가능한 웹 기반 노트북
파라미터를 바꿔가면서 결과를 보면서
작업을 이어갈 수 있고
•
• 다양한 인터프리터 사용가능
• 쉬운 시각화
Apache Zeppelin
→ Spark!
Zeppelin
대화식 분석이 가능한 웹 기반 노트북
다양한 인터프리터를 사용할 수 있기 때문에
•
• 다양한 인터프리터 사용가능
• 쉬운 시각화
Apache Zeppelin
→ Spark!
Zeppelin
대화식 분석이 가능한 웹 기반 노트북
Spark 인터프리터부터, 각종 언어들, JDBC 등
여러 가지를 연동하여 사용할 수 있습니다.
•
• 다양한 인터프리터 사용가능
• 쉬운 시각화
Apache Zeppelin
→ Spark!
Zeppelin
대화식 분석이 가능한 웹 기반 노트북
마지막으로 가장 유용하다고 생각하는 기능 중 하나인
시각화인데요.
•
• 다양한 인터프리터 사용가능
• 쉬운 시각화
Apache Zeppelin
→ Spark!
Zeppelin
대화식 분석이 가능한 웹 기반 노트북
별다른 처리 없이도
결과에 따라서 잘 알아서 시각화를 해줍니다.
SparkSQL
보시는 것은 실제 Zeppelin의 사용 모습입니다.
SparkSQL
이렇게 Spark SQL 쿼리로 분석할 수 있고
(쿼리 내용 중요하지 않음)
다이나믹 폼 사용가능
실제 쿼리의 조건절에 들어가는 값을
다양하게 바꿀 수 있는 다이나믹 폼도 지원합니다.
다양한 그래프
또한, 단순 테이블, 막대 그래프, 파이 그래프 등
여러 가지 그래프를 지원하고요.
CSV 다운로드
결과를 CSV로 다운로드할 수 있습니다.
스케줄링
그리고 노트북을 특정 시간대에 자동으로 실행하도록
스케줄링
스케줄링이 가능합니다.
스케줄링
보시는 바와 같이 Cron Expression으로
자동실행 스케줄을 지정할 수 있습니다.
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
이렇게 Apache Spark와 Apache Zeppelin의
클러스터를 구성하는 데에는
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
AWS의 EMR 서비스를 사용하고 있습니다.
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
Spark 클러스터를 클릭 몇 번으로 쉽게 구성가능하고
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
여기에 Zeppelin도 같이 구성할 수 있습니다.
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
게다가 AWS에서 유휴자원을 싼 가격에 사용할 수 있는
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
스팟 인스턴스도 사용가능한데요.
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
도쿄 리전 r4.4xlarge 기준으로
4분의 1가격에 사용가능합니다.
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
또한 쉽게 확장 및 축소가 가능하다는 것도 장점입니다.
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
10개 인스턴스로 5분 1개 인스턴스로 50분
아주 단순하게 생각했을 때
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
10개 인스턴스로 5분 1개 인스턴스로 50분
10개 인스턴스로 5분동안 처리하는 것과
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
10개 인스턴스로 5분 1개 인스턴스로 50분
1개 인스턴스로 50분동안 처리하는 것이
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
10개 인스턴스로 5분 1개 인스턴스로 50분
비용
만약 같은 비용이라면
• Spark 클러스터를 손쉽게 구성
• 스팟 인스턴스 사용가능
• 쉬운 확장 및 축소
AWS EMR
EMR
+ Zeppelin
10개 인스턴스로 5분 1개 인스턴스로 50분
비용
당연히 많은 인스턴스로 짧은 시간 동안
처리하는 게 훨씬 이득이겠죠.
정기적인 배치 잡은 어떻게 실행하나요?
하지만 정기적으로 필요한 분석을 위한 배치잡은
어떻게 실행하는 지 궁금하실 수 있는데요.
Zeppelin의 노트북 스케줄 기능 ?
여기서 아까 보셨던 Zeppelin의
노트북 스케줄 기능을 생각하실 수 있습니다.
Zeppelin의 노트북 스케줄 기능 ?
실패 시 자동 재시도
완료 시 클러스터 반납
하지만 Zeppelin은
실패시 자동으로 재시도하거나
Zeppelin의 노트북 스케줄 기능 ?
실패 시 자동 재시도
완료 시 클러스터 반납
완료 시 인스턴스를 반납하는 것과 같은 동작은
할 수 없기 때문에
Zeppelin의 노트북 스케줄 기능 ?
실패 시 자동 재시도
완료 시 클러스터 반납
Ad-hoc 분석용으로만 사용
저희는 Zeppelin을
Ad-hoc 분석용으로만 사용하고 있습니다.
DataPipeline
그 대안으로 AWS의 DataPipeline이라는
서비스를 사용하고 있습니다.
보시는 것은 DataPipeline 서비스를
AWS 콘솔에서 봤을 때의 모습인데요.
다이어그램을 간단히 설명드리면
매일 00시에
매일 특정 시간에
매일 00시에
클러스터를 실행하고
EMR 클러스터를 띄우고
매일 00시에
클러스터를 실행하고
특정 Job을 수행해라특정 Job을 수행해라라는 의미인데요.
매일 00시에
클러스터를 실행하고
특정 Job을 수행해라실제로 Job이 실패했을 때 재시도하거나
매일 00시에
클러스터를 실행하고
특정 Job을 수행해라실행이 끝났을 때
클러스터를 모두 종료할 수 있기 때문에
매일 00시에
클러스터를 실행하고
특정 Job을 수행해라비용을 절감할 수 있습니다.
분석 클러스터
S3 ZeppelinSpark
AWS EMR
DataPipeline
이렇게 저희의 분석 클러스터가
어떻게 구성되었는지 말씀드렸는데요.
분석 클러스터
S3 ZeppelinSpark
AWS EMR
DataPipeline
마지막으로 전체 아키텍처를 정리를 해보면
게임
서버
Fluentd
S3Lambda
Lambda
Kinesis
ES
ZeppelinSpark
AWS EMR
DataPipeline
다음과 같이 표현될 수 있습니다.
S3Lambda ZeppelinSpark
AWS EMR
DataPipeline
게임
서버
Fluentd
Lambda
Kinesis
ES
5초 이내
1. 로그를 확인하기 까지
로그를 확인하는 데 까지
5초 이내로 확인할 수 있고
S3Lambda
Lambda ES
ZeppelinSpark
AWS EMR
DataPipeline
게임
서버
Fluentd
2. 로그 유입량이 증가하면?
Kinesis
확장 포인트
만약 로그 유입량이 증가하더라도
S3Lambda
Lambda ES
ZeppelinSpark
AWS EMR
DataPipeline
게임
서버
Fluentd
2. 로그 유입량이 증가하면?
Kinesis
확장 포인트
Kinesis의 샤드 개수만 증가시키면 됩니다.
S3Lambda
Lambda ES
ZeppelinSpark
AWS EMR
DataPipeline
게임
서버
Fluentd
2. 로그 유입량이 증가하면?
Kinesis
확장 포인트
아, Fluentd는 저희 같은 경우
아까 말씀드렸다시피
S3Lambda
Lambda ES
ZeppelinSpark
AWS EMR
DataPipeline
게임
서버
Fluentd
2. 로그 유입량이 증가하면?
Kinesis
확장 포인트
각각의 호스트에 하나씩 존재하므로
호스트 개수만큼 알아서 확장하는 구조입니다.
• 도쿄 리전 기준
• 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도)
• Kinesis 샤드 2개 + 데이터 PUT 비용
• Lambda (처리시간 1초)
→ 약 $90
→ 약 $20
3. Kinesis + Lambda 월 유지비용
→ 월 $110 정도로 유지 비용(저장비용 제외)
• 도쿄 리전 기준
• 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도)
• Kinesis 샤드 2개 + 데이터 PUT 비용
• Lambda (처리시간 1초)
→ 약 $90
→ 약 $20
3. Kinesis + Lambda 월 유지비용
→ 월 $110 정도로 유지 비용(저장비용 제외)
여기서 잠시 로그 수집 파이프라인의 비용을 살펴보면
• 도쿄 리전 기준
• 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도)
• Kinesis 샤드 2개 + 데이터 PUT 비용
• Lambda (처리시간 1초)
→ 약 $90
→ 약 $20
3. Kinesis + Lambda 월 유지비용
→ 월 $110 정도로 유지 비용(저장비용 제외)
만약에 초당 1000개의 로그가 지속적으로 유입되고
• 도쿄 리전 기준
• 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도)
• Kinesis 샤드 2개 + 데이터 PUT 비용
• Lambda (처리시간 1초)
→ 약 $90
→ 약 $20
3. Kinesis + Lambda 월 유지비용
→ 월 $110 정도로 유지 비용(저장비용 제외)
초당 2MB정도 유입된다고 가정하면
• 도쿄 리전 기준
• 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도)
• Kinesis 샤드 2개 + 데이터 PUT 비용
• Lambda (처리시간 1초)
→ 약 $90
→ 약 $20
3. Kinesis + Lambda 월 유지비용
→ 월 $110 정도로 유지 비용(저장비용 제외)
월 5TB정도의 로그가 발생하는데요.
• 도쿄 리전 기준
• 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도)
• Kinesis 샤드 2개 + 데이터 PUT 비용
• Lambda (처리시간 1초)
→ 약 $90
→ 약 $20
3. Kinesis + Lambda 월 유지비용
→ 월 $110 정도로 유지 비용(저장비용 제외)
이 때 최소로 필요한 Kinesis 샤드 2개와
• 도쿄 리전 기준
• 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도)
• Kinesis 샤드 2개 + 데이터 PUT 비용
• Lambda (처리시간 1초)
→ 약 $90
→ 약 $20
3. Kinesis + Lambda 월 유지비용
→ 월 $110 정도로 유지 비용(저장비용 제외)데이터를 기록하는 비용, Lambda에서 처리하는 비용을
모두 합쳐도
• 도쿄 리전 기준
• 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도)
• Kinesis 샤드 2개 + 데이터 PUT 비용
• Lambda (처리시간 1초)
→ 약 $90
→ 약 $20
3. Kinesis + Lambda 월 유지비용
→ 월 $110 정도로 유지 비용(저장비용 제외)
월 110달러 정도의 유지 비용이 발생합니다.
• 도쿄 리전 기준
• 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도)
• Kinesis 샤드 2개 + 데이터 PUT 비용
• Lambda (처리시간 1초)
→ 약 $90
→ 약 $20
3. Kinesis + Lambda 월 유지비용
→ 월 $110 정도로 유지 비용(저장비용 제외)물론 이건 저장비용을 제외하고,
최소로 맞춘 스펙이니 참고만 부탁드립니다.
게임
서버
Fluentd
S3Lambda
Lambda
Kinesis
ES
DataPipeline
4. 빠르게 분석하고 싶을 때 확장 포인트
ZeppelinSpark
AWS EMR
분석을 빠르게 하고 싶을 때는
게임
서버
Fluentd
S3Lambda
Lambda
Kinesis
ES
DataPipeline
4. 빠르게 분석하고 싶을 때 확장 포인트
ZeppelinSpark
AWS EMR
EMR 클러스터만 확장해주면 됩니다.
5. 대규모 분석 비용
• 모든 로그에 대하여
• r4.8xlarge X 10 스팟 인스턴스, 도쿄 리전 기준
• 생성된 모든 섬의 개수
• 가장 많이 채집된 자원(10위까지)
• 모든 섬의 날짜별 일일 활성 유저수
→ 5분 = $1 미만
→ 10분 = 약$1
→ 15분 = 약 $ 1.3
프로비저닝 시간 제외, 2018년 4월 24일 기준
만약 대규모 분석을 위해서
5. 대규모 분석 비용
• 모든 로그에 대하여
• r4.8xlarge X 10 스팟 인스턴스, 도쿄 리전 기준
• 생성된 모든 섬의 개수
• 가장 많이 채집된 자원(10위까지)
• 모든 섬의 날짜별 일일 활성 유저수
→ 5분 = $1 미만
→ 10분 = 약$1
→ 15분 = 약 $ 1.3
프로비저닝 시간 제외, 2018년 4월 24일 기준
도쿄 리전을 기준으로 r4.8xlarge 타입의 인스턴스를
스팟 인스턴스로 10개를 띄우고
5. 대규모 분석 비용
• 모든 로그에 대하여
• r4.8xlarge X 10 스팟 인스턴스, 도쿄 리전 기준
• 생성된 모든 섬의 개수
• 가장 많이 채집된 자원(10위까지)
• 모든 섬의 날짜별 일일 활성 유저수
→ 5분 = $1 미만
→ 10분 = 약$1
→ 15분 = 약 $ 1.3
프로비저닝 시간 제외, 2018년 4월 24일 기준
분석이 끝나는 즉시 종료한다면
5. 대규모 분석 비용
• 모든 로그에 대하여
• r4.8xlarge X 10 스팟 인스턴스, 도쿄 리전 기준
• 생성된 모든 섬의 개수
• 가장 많이 채집된 자원(10위까지)
• 모든 섬의 날짜별 일일 활성 유저수
→ 5분 = $1 미만
→ 10분 = 약$1
→ 15분 = 약 $ 1.3
프로비저닝 시간 제외, 2018년 4월 24일 기준
보시는 바와 같이 시간과 비용을 최대한 절감할 수 있습니다.
#4 ‘잘’ 사용하기
다음으로는 이런 아키텍처에서
#4 ‘잘’ 사용하기
각각의 구성요소들을 잘 사용하기 위한 방법들을
말씀드리려고 합니다.
게임
서버
Fluentd
S3Lambda
Lambda ES
ZeppelinSpark
AWS EMR
DataPipeline
Kinesis
확장 포인트
Kinesis 샤드 개수는 어떻게 결정하나요?
첫 번째로,
방금 로그 유입량이 늘어나면
게임
서버
Fluentd
S3Lambda
Lambda ES
ZeppelinSpark
AWS EMR
DataPipeline
Kinesis
확장 포인트
Kinesis 샤드 개수는 어떻게 결정하나요?
Kinesis의 샤드개수를 늘리면 된다고
말씀드렸는데요.
• 샤드의 처리량 제한
• Lambda의 처리속도
Kinesis 샤드 개수는 어떻게 결정하나요?
사실 이 Kinesis 샤드 개수를 결정하기 위해
• 샤드의 처리량 제한
• Lambda의 처리속도
Kinesis 샤드 개수는 어떻게 결정하나요?
고려해야 할 두 가지가 있습니다.
Kinesis 샤드 개수는 어떻게 결정하나요?
• 샤드의 처리량 제한
• Lambda의 처리속도
샤드 하나에 초당 처리할 수 있는 처리량 제한이 있고요.
Kinesis 샤드 개수는 어떻게 결정하나요?
• 샤드의 처리량 제한
• Lambda의 처리속도
또한 Lambda의 처리속도를 고려해야합니다.
Lambda Iterator age
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
이 그래프는 Lambda의 Iterator age라는 메트릭입니다.
Lambda Iterator age
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
Lambda가 가장 최근에 처리한 레코드의
Lambda Iterator age
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
Kinesis에 실제로 처음 기록된 시간과
Lambda Iterator age
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
Lambda가 이 레코드를 처리하기 위해 이벤트를 받은
Lambda Iterator age
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
시간 차이인데요.
Lambda Iterator age
증가하면 안됨
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
결국 Kinesis에 데이터가 들어오는 속도보다
Lambda Iterator age
증가하면 안됨
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
Lambda의 처리속도가 느리면
Lambda Iterator age
증가하면 안됨
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
메트릭이 계속 상승곡선을 이루게 됩니다.
Lambda Iterator age
증가하면 안됨
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
여기서 Lambda는 이벤트가 일어나는 만큼
자동으로 확장하지 않느냐?라고 생각하실 수 있는데요.
Lambda Iterator age
증가하면 안됨
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
Lambda를 일반적인 사용예인
API형태로 사용할 때와 Kinesis를 트리거할 때는
Lambda Iterator age
증가하면 안됨
가장 최근에 처리한 레코드가
Kinesis에 기록된 시간과
Lambda가 레코드를 받은
시간차이
다른 동작 형태를 보입니다.
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
예를 들어 Kinesis에 3개의 샤드가 존재하고
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
Lambda가 이를 트리거한다고 가정해보겠습니다.
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
보통은 Kinesis의 샤드에는
랜덤하게 데이터가 분배되는데
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
데이터가 1번 샤드에 하나 들어오면
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
!
Lambda는
“아! 이번 샤드에 데이터가 들어왔구나!”하고
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
!
이 것을 처리하려고 하는데요.
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
이때 Lambda는 1번 샤드의 데이터를 처리합니다.
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
만약에 모든 데이터가 다 처리되면
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
더 이상 Lambda가 실행되지 않고요.
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
물론 여기서 데이터를 처리하더라도
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
Kinesis에 데이터는 계속 보존되는데
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
그림에서는 이해를 돕기 위해 없앴습니다.
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
그리고 다시 3번 샤드에 데이터가 들어오면
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
다시 이것을 처리하게 되겠죠.
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
만약 3개의 샤드에 동시에 데이터가 들어오면
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
Lambda는 3개 샤드만큼 동시실행하여
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
각각의 샤드에 대해서 처리하게 됩니다.
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
1초 마다 배치 처리
만약 지속적으로 데이터가 들어오는 상황에서는
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
1초 마다 배치 처리
각각의 샤드에 대해서
1초마다 동기적으로 배치처리를 하게 됩니다.
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
1초 마다 배치 처리
샤드 개수 증가 Lambda 동시실행
결국 Lambda는 최대 Kinesis의 샤드개수만큼
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
1초 마다 배치 처리
샤드 개수 증가 Lambda 동시실행
동시실행이 될 수 있기 때문에
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
1초 마다 배치 처리
샤드 개수 증가 Lambda 동시실행
Kinesis의 샤드 개수를 증가시키는 것은
Shard 1
Kinesis
Lambda
Shard 2
Shard 3
1초 마다 배치 처리
샤드 개수 증가 Lambda 동시실행
Lambda의 동시실행 수를 높일 수 있다는 것을 의미합니다.
Kinesis – Lambda 처리속도를 높이는 방법
1. Kinesis stream의 샤드 개수를 증가시킨다.
2. Lambda의 가용 메모리를 증가시킨다.
(Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨)
여기서 Lambda의 처리속도를 높이는 방법을 정리해보면
Kinesis – Lambda 처리속도를 높이는 방법
1. Kinesis stream의 샤드 개수를 증가시킨다.
2. Lambda의 가용 메모리를 증가시킨다.
(Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨)
Kinesis의 샤드 개수를 증가시켜서
Lambda의 동시 실행 수를 늘리는 방법이 있고
Kinesis – Lambda 처리속도를 높이는 방법
1. Kinesis stream의 샤드 개수를 증가시킨다.
2. Lambda의 가용 메모리를 증가시킨다.
(Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨)
Lambda는 설정된 메모리 크기에 따라
Kinesis – Lambda 처리속도를 높이는 방법
1. Kinesis stream의 샤드 개수를 증가시킨다.
2. Lambda의 가용 메모리를 증가시킨다.
(Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨)
CPU 성능이 조절되기 때문에
Kinesis – Lambda 처리속도를 높이는 방법
1. Kinesis stream의 샤드 개수를 증가시킨다.
2. Lambda의 가용 메모리를 증가시킨다.
(Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨)
Lambda의 가용 메모리를 증가시켜서
CPU 성능을 높이는 방법이 있습니다.
Kinesis – Lambda 처리속도를 높이는 방법
1. Kinesis stream의 샤드 개수를 증가시킨다.
2. Lambda의 가용 메모리를 증가시킨다.
(Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨)
하지만 저희의 경우 CPU 보다는
Kinesis – Lambda 처리속도를 높이는 방법
1. Kinesis stream의 샤드 개수를 증가시킨다.
2. Lambda의 가용 메모리를 증가시킨다.
(Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨)
I/O에 인텐시브하기 때문에 두 번째 방법은 배제하고 있습니다.
로그파일 포맷: JSON
• 복잡한 게임 시스템 → 복잡한 로그 스키마
• Lambda는 최대 1000개의 로그를 하나의 파일로 저장
(Kinesis 샤드의 초당 최대 쓰기 개수)
이제 저희가 로그를 어떻게 저장하는 지 말씀드리려고 합니다.
로그파일 포맷: JSON
• 복잡한 게임 시스템 → 복잡한 로그 스키마
• Lambda는 최대 1000개의 로그를 하나의 파일로 저장
(Kinesis 샤드의 초당 최대 쓰기 개수)
저희는 아이템 구조 등 복잡한 게임시스템으로
로그파일 포맷: JSON
• 복잡한 게임 시스템 → 복잡한 로그 스키마
• Lambda는 최대 1000개의 로그를 하나의 파일로 저장
(Kinesis 샤드의 초당 최대 쓰기 개수)
보다 유연한 로그 스키마가 필요했고
로그파일 포맷: JSON
• 복잡한 게임 시스템 → 복잡한 로그 스키마
• Lambda는 최대 1000개의 로그를 하나의 파일로 저장
(Kinesis 샤드의 초당 최대 쓰기 개수)
때문에 JSON 형식으로 로그를 저장하고 있습니다.
로그파일 포맷: JSON
• 복잡한 게임 시스템 → 복잡한 로그 스키마
• Lambda는 최대 1000개의 로그를 하나의 파일로 저장
(Kinesis 샤드의 초당 최대 쓰기 개수)
여기서 Lambda는 최대 1000개의 로그를
하나의 파일로 저장하는데요.
엄청나게 많은 파일 개수 → 네트워크 오버헤드
로그파일 포맷: JSON
• 복잡한 게임 시스템 → 복잡한 로그 스키마
• Lambda는 최대 1000개의 로그를 하나의 파일로 저장
(Kinesis 샤드의 초당 최대 쓰기 개수)
사실 이런 저장방식은
엄청나게 많은 파일을 생성시키고
엄청나게 많은 파일 개수 → 네트워크 오버헤드
로그파일 포맷: JSON
• 복잡한 게임 시스템 → 복잡한 로그 스키마
• Lambda는 최대 1000개의 로그를 하나의 파일로 저장
(Kinesis 샤드의 초당 최대 쓰기 개수)
결국 분석 시에 네트워크 오버헤드를 유발하게 됩니다.
JSON → Parquet
때문에 저희는 JSON을 Parquet 형식의
파일로 가공하는데요.
JSON → Parquet
많은 수의 파일을 단지 몇 개로
분할된 Parquet 파일로 변환하고 있고
JSON → Parquet
이런 변환을 1시간 마다 배치잡으로 처리하고 있습니다.
{
"type":"ItemPurchased",
"seller_id":"1a2b3c4d5e6f",
"@time":"2018-04-24T……",
"item":{
"level":12,
"durability":1234,
"tags":{
...
},
}
...
}
JSON실제 저희 로그 형태를 보면
중첩된 데이터 구조로 이루어져 있는데
Parquet
이런 중첩 데이터 구조를 모두 지원하면서도
Parquet
구조화된 형태를 가지는 Parquet 포맷으로 변환하게됩니다.
Parquet
• 스키마를 가진 컬럼형 저장 포맷
• 복잡한 중첩 데이터 구조도 지원
• 기본적으로 Snappy 압축
• Column projection
• Predicate pushdown
Parquet 파일 형식에 대해서 소개해드리면
Parquet
• 스키마를 가진 컬럼형 저장 포맷
• 복잡한 중첩 데이터 구조도 지원
• 기본적으로 Snappy 압축
• Column projection
• Predicate pushdown
먼저 스키마를 가진 컬럼형 저장 포맷이라고
말씀드릴 수 있습니다.
Parquet
• 스키마를 가진 컬럼형 저장 포맷
• 복잡한 중첩 데이터 구조도 지원
• 기본적으로 Snappy 압축
• Column projection
• Predicate pushdown
또한 구조화된 포맷임에도 불구하고
Parquet
• 스키마를 가진 컬럼형 저장 포맷
• 복잡한 중첩 데이터 구조도 지원
• 기본적으로 Snappy 압축
• Column projection
• Predicate pushdown
복잡한 중첩데이터 구조도 지원하고요.
Parquet
→ 네트워크 트래픽 감소
• 스키마를 가진 컬럼형 저장 포맷
• 복잡한 중첩 데이터 구조도 지원
• 기본적으로 Snappy 압축
• Column projection
• Predicate pushdown
기본적으로 Snappy 형식의 압축을 하고있고
Parquet
→ 네트워크 트래픽 감소
• 스키마를 가진 컬럼형 저장 포맷
• 복잡한 중첩 데이터 구조도 지원
• 기본적으로 Snappy 압축
• Column projection
• Predicate pushdown
Column projection, Predicate Pushdown
기능을 제공합니다.
Parquet
→ 네트워크 트래픽 감소
• 스키마를 가진 컬럼형 저장 포맷
• 복잡한 중첩 데이터 구조도 지원
• 기본적으로 Snappy 압축
• Column projection
• Predicate pushdown
Snappy 압축과 아래 두가지 기능은
Parquet
→ 네트워크 트래픽 감소
• 스키마를 가진 컬럼형 저장 포맷
• 복잡한 중첩 데이터 구조도 지원
• 기본적으로 Snappy 압축
• Column projection
• Predicate pushdown
네트워크 트래픽을 감소 시킬 수 있습니다.
Column projection
이 Column projection에 대해서 간단히 설명을 드리면
Column projection
4월 1일에 접속한 레벨 60의 플레이어 수
SELECT
COUNT(DISTINCT(player_entity_id))
FROM PlayerEntered_asia_a
WHERE __date="2018-04-01"
AND player_level=60
4월 1일에 접속한 레벨 60의 플레이어 수를
추출하는 쿼리를 예제로 들 수 있습니다.
Column projection
쿼리에 필요한 컬럼만 스캔
+- *FileScan parquet
[player_entity_id#44,player_level#45,__date#53]
이 쿼리의 플랜을 보면
Column projection
쿼리에 필요한 컬럼만 스캔
+- *FileScan parquet
[player_entity_id#44,player_level#45,__date#53]
쿼리에 실제로 필요한
플레이어 아이디와, 레벨, 날짜만 스캔하는 것을 알 수 있습니다.
Column projection
쿼리에 필요한 컬럼만 스캔
+- *FileScan parquet
[player_entity_id#44,player_level#45,__date#53]
결국 컬럼형 저장방식이기 때문에
Column projection
쿼리에 필요한 컬럼만 스캔
+- *FileScan parquet
[player_entity_id#44,player_level#45,__date#53]
쿼리에 필요한 컬럼만 스캔하여
Column projection
쿼리에 필요한 컬럼만 스캔
+- *FileScan parquet
[player_entity_id#44,player_level#45,__date#53]
네트워크 트래픽을 낮출 수 있습니다.
Predicate pushdown
레벨 60인 데이터만 필터링
PushedFilteres:
[IsNotNull(player_level),
EqualTo(player_level,60)]
또 Predicate pushdown은 같은 예제로
Predicate pushdown
레벨 60인 데이터만 필터링
PushedFilteres:
[IsNotNull(player_level),
EqualTo(player_level,60)]
메타데이터에 저장된 통계값을 이용해
Predicate pushdown
레벨 60인 데이터만 필터링
PushedFilteres:
[IsNotNull(player_level),
EqualTo(player_level,60)]
레벨이 60인 데이터만 필터링하여 스캔합니다.
Predicate pushdownColumn projection
이렇게 Column Projection과
Predicate pushdown을 활용하여
Predicate pushdownColumn projection
최대한 필요한 데이터만 읽도록 하여
Predicate pushdownColumn projection
네트워크 트래픽을 낮출 수 있는데요.
Table Partitioning
• 데이터 스캔 범위를 제한가능
• 저장경로에 '<key>=<value>' 형태로 분리
여기에 테이블 파티셔닝이라는 기능을 이용하면
Table Partitioning
→ 네트워크 트래픽 감소• 데이터 스캔 범위를 제한가능
• 저장경로에 '<key>=<value>' 형태로 분리
추가적으로 네트워크 트래픽을 감소시킬 수 있습니다.
Table Partitioning
s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename>
→ 네트워크 트래픽 감소• 데이터 스캔 범위를 제한가능
• 저장경로에 '<key>=<value>' 형태로 분리
여러 가지 방법이 있긴 하지만
Table Partitioning
s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename>
→ 네트워크 트래픽 감소• 데이터 스캔 범위를 제한가능
• 저장경로에 '<key>=<value>' 형태로 분리
저장경로에 Key=Value 형태로
중간 경로를 지정하는 형태로 사용할 수 있습니다.
Table Partitioning
s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename>
→ 네트워크 트래픽 감소• 데이터 스캔 범위를 제한가능
• 저장경로에 '<key>=<value>' 형태로 분리
실제로 저희는 날짜별로 파티셔닝을 하고 있는데
Table Partitioning
SELECT
COUNT(DISTINCT(player_entity_id))
FROM PlayerEntered_asia_a
WHERE __date="2018-04-01"
AND player_level=60
아까와 같이 4월 1일에 접속한
레벨이 60인 플레이어 수를 구하는 예제에서
SELECT
COUNT(DISTINCT(player_entity_id))
FROM PlayerEntered_asia_a
WHERE __date="2018-04-01"
AND player_level=60
실제 컬럼처럼 사용가능
Table Partitioning
WHERE __date="2018-04-01"
s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename>
아까 저장경로 상에서 지정한 date라는 파티션을
SELECT
COUNT(DISTINCT(player_entity_id))
FROM PlayerEntered_asia_a
WHERE __date="2018-04-01"
AND player_level=60
실제 컬럼처럼 사용가능
Table Partitioning
WHERE __date="2018-04-01"
s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename>
실제 컬럼처럼 사용가능하고요.
SELECT
COUNT(DISTINCT(player_entity_id))
FROM PlayerEntered_asia_a
WHERE __date="2018-04-01"
AND player_level=60
쿼리 플랜에서 동작을 확인할 수 있다.
Table Partitioning
PartitionFilters: [isnotnull(__date#53),
(cast(__date#53as string)=2018-04-01)]
쿼리플랜에서도 다음과 같이 파티션 필터가 동작하면서
SELECT
COUNT(DISTINCT(player_entity_id))
FROM PlayerEntered_asia_a
WHERE __date="2018-04-01"
AND player_level=60
쿼리 플랜에서 동작을 확인할 수 있다.
Table Partitioning
PartitionFilters: [isnotnull(__date#53),
(cast(__date#53as string)=2018-04-01)]
date가 4월 1일인 파티션을 필터링하는 것을 볼 수 있습니다.
SELECT
COUNT(DISTINCT(player_entity_id))
FROM PlayerEntered_asia_a
WHERE __date="2018-04-01"
AND player_level=60
쿼리 플랜에서 동작을 확인할 수 있다.
Table Partitioning
PartitionFilters: [isnotnull(__date#53),
(cast(__date#53as string)=2018-04-01)]
실제로 해당되는 파티션의 데이터만
S3에서 읽기 때문에
SELECT
COUNT(DISTINCT(player_entity_id))
FROM PlayerEntered_asia_a
WHERE __date="2018-04-01"
AND player_level=60
쿼리 플랜에서 동작을 확인할 수 있다.
Table Partitioning
PartitionFilters: [isnotnull(__date#53),
(cast(__date#53as string)=2018-04-01)]
훨씬 네트워크 트래픽을 감소시킬 수 있습니다.
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
다음은 로그 스키마 관리인데요.
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
결국은 JSON에서 Parquet로
구조화된 데이터 유형을 사용하기 때문에
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
로그 스키마 관리가 필요합니다.
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
먼저 저희는 접속로그, 채집로그 등
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
로그 유형별로 스키마를 가지고 있습니다.
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
새롭게 컨텐츠가 들어갈 때
새로운 스키마를 쉽게 추가할 수 있지만
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
기존에 존재하는 스키마를 변경할 땐
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
약간 제한되는 것들이 있습니다.
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
약간 제한되는 것들이 있습니다.
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
예를 들어, 컬럼 이름을 바꾼다고 하면
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
이미 적재되어 있는 모든 로그에 대하여
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
새로운 컬럼 이름으로 바꿔서 다시 저장하는
마이그레이션 비용이 매우 크기 때문입니다.
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
→ 컬럼 추가만 가능! 하위호환성을 유지하여야 한다.
때문에 저희는 컬럼 추가만 가능하게 하여
로그 스키마 관리
• 로그는 다양한 스키마를 가진다.
• 접속로그, 채집로그, 구매로그 등
• 새로운 스키마는 언제든지 추가될 수 있어야 한다.
• 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다.
→ 컬럼 추가만 가능! 하위호환성을 유지하여야 한다.
하위호환성을 유지하는 정책을 두고 있습니다.
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
저희는 서버 코드 상에서 로그 스키마를 관리하는데요.
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
스키마 별로 클래스가 존재하고
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
이 클래스로부터 데이터를 담은 객체를 생성하여
로그를 전송합니다.
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
새로운 버전 배포 시에
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
각각의 스키마 별로
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
SparkSQL에서 StructType이라는 클래스에서 다루는
JSON 포맷으로 스키마를 추출하고
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
이 것을 따로 특정 S3 버킷에 저장합니다.
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
그리고 JSON 파일을 Parquet로 변환하는 배치잡에서는
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
아까 저장했던 스키마 중
가장 최근 버전의 스키마를 읽고 처리하는데요.
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
스키마 저장소를 따로 관리하기 때문에
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
새로 추가된 스키마에 대해서도
로그 스키마 업데이트
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
별다른 처리 없이 배치잡에서 알 수 있습니다.
로그 스키마 업데이트
schema = StructType.fromJson(schema_json)
Parquet 변환 시 로드
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
PySpark
로그 스키마 업데이트
schema = StructType.fromJson(schema_json)
Parquet 변환 시 로드
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
PySpark
JSON으로된 로그를 Parquet로 변환시
로그 스키마 업데이트
schema = StructType.fromJson(schema_json)
Parquet 변환 시 로드
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
PySpark
보시는 코드와 같이 JSON으로된 스키마 파일을 로드하여
로그 스키마 업데이트
schema = StructType.fromJson(schema_json)
Parquet 변환 시 로드
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
PySpark
StructType 객체를 생성하고
로그 스키마 업데이트
schema = StructType.fromJson(schema_json)
Parquet 변환 시 로드
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
PySpark
JSON 로그의 스키마를 지정하고 있습니다.
로그 스키마 업데이트
schema = StructType.fromJson(schema_json)
Parquet 변환 시 로드
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
PySpark
물론 JSON 로그로 부터 스키마를 추론할 수 있기도 하지만
로그 스키마 업데이트
schema = StructType.fromJson(schema_json)
Parquet 변환 시 로드
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
PySpark
성능이 느려지고
로그 스키마 업데이트
schema = StructType.fromJson(schema_json)
Parquet 변환 시 로드
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
PySpark
명시적인 것이 훨씬 좋다는 판단 하에
로그 스키마 업데이트
schema = StructType.fromJson(schema_json)
Parquet 변환 시 로드
1. 스키마 별 Class 추가 또는 업데이트
2. 배포 시 Spark StructType JSON 포맷으로 추출
3. AWS S3에 저장
4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행
PySpark
스키마를 따로 정의하고 관리하는 방법을 사용하고 있습니다.
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
다음으로는 EMR에서 Spark 클러스터를 할당하는 팁인데요.
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
인 메모리 방식이기 때문에
많은 메모리가 필요할 수 있어서
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
메모리 최적화 타입인 r4 타입을 선호하고 있습니다.
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
또한 작은 인스턴스 여러 개 보다는
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
큰 인스턴스 하나를 사용하고 있는데
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
그 이유는 좋은 인스턴스일수록
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
AWS에서 더 높은 네트워크 속도를 제공하고 있고
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
EMR에서 Spark를 사용할 때
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
YARN이라는 리소스 매니저를 사용하는데
EMR Spark 클러스터 스펙
• 메모리가 중요하므로 r4 타입을 선호
• 작은 인스턴스 4개 보다 큰 인스턴스 1개로
• 좋은 인스턴스가 네트워크 속도도 더 빠르다
• EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다
이 때 YARN 컨테이너에 할당하는
메모리 비율이 더 크기 때문입니다.
#5 개선할 점
네, 여기까지 저희 로그 시스템에 대한 소개를 마쳤습니다.
#5 개선할 점
그래서 결론이 “완벽한 로그 시스템인가?” 에 대하여
#5 개선할 점
실제 운영결과, 앞서 말했던 목표를 달성하였지만
#5 개선할 점
몇 가지 분명 불편한 점이 있었습니다.
#5 개선할 점
마지막으로 개선할 점을 말씀드리면서
정리를 하고자합니다.
• 분석가는 언제나 부족
• 비 개발자도 분석하기도 쉬웠으면
• SQL은 과연 쉬운가…?
• 사실상 대중화 실패
• 하는 사람만 한다.
분석의 대중화
먼저 분석의 대중화가 어려웠습니다.
• 분석가는 언제나 부족
• 비 개발자도 분석하기도 쉬웠으면
• SQL은 과연 쉬운가…?
• 사실상 대중화 실패
• 하는 사람만 한다.
분석의 대중화
분석에 대한 수요는 많지만
분석가는 언제나 부족합니다.
• 분석가는 언제나 부족
• 비 개발자도 분석하기도 쉬웠으면
• SQL은 과연 쉬운가…?
• 사실상 대중화 실패
• 하는 사람만 한다.
분석의 대중화
때문에 비 개발자도 분석하기 쉬웠으면
이라는 생각도 하는데요.
• 분석가는 언제나 부족
• 비 개발자도 분석하기도 쉬웠으면
• SQL은 과연 쉬운가…?
• 사실상 대중화 실패
• 하는 사람만 한다.
분석의 대중화
사실 이런 점을 위해서
나름 간단한 분석은 쉽게 할 수 있도록
• 분석가는 언제나 부족
• 비 개발자도 분석하기도 쉬웠으면
• SQL은 과연 쉬운가…?
• 사실상 대중화 실패
• 하는 사람만 한다.
분석의 대중화
SQL을 사용할 수 있는 것을 목표로 하였습니다만
• 분석가는 언제나 부족
• 비 개발자도 분석하기도 쉬웠으면
• SQL은 과연 쉬운가…?
• 사실상 대중화 실패
• 하는 사람만 한다.
분석의 대중화
사실상 대중화는 쉽지 않았습니다.
• 분석의 규모에 따라
• 클러스터 크기가 자동으로 조절되었으면
분석 규모에 따른 오토 스케일링
또한 분석 규모에 따라
오토 스케일링이 되었으면 좋겠다라는 생각을 했습니다.
• 분석의 규모에 따라
• 클러스터 크기가 자동으로 조절되었으면
분석 규모에 따른 오토 스케일링
비용을 좀 더 효과적으로 절감하고
• 분석의 규모에 따라
• 클러스터 크기가 자동으로 조절되었으면
분석 규모에 따른 오토 스케일링
시간을 효율적으로 사용할 수 있었으면 하는
바람이 있습니다.
시각화의 다양화
• 한편으로는 복잡한 시각화가 필요할 때도 있다.
• Zeppelin으로는 아직 제한적
한편으로는 Zeppelin에만
시각화에 대한 상당부분을 의존하고 있기 때문에
시각화의 다양화
• 한편으로는 복잡한 시각화가 필요할 때도 있다.
• Zeppelin으로는 아직 제한적
복잡한 시각화의 경우
시각화의 다양화
• 한편으로는 복잡한 시각화가 필요할 때도 있다.
• Zeppelin으로는 아직 제한적
Jupyter notebook에서 따로 시각화하고 있는데요.
시각화의 다양화
• 한편으로는 복잡한 시각화가 필요할 때도 있다.
• Zeppelin으로는 아직 제한적
이 부분도 아직은 아쉬움으로 남고 있습니다.
로그 스키마 변경
• 이미 쌓인 로그에 대하여 마이그레이션 불가능
• 오직 컬럼 추가만 가능
세 번째는 아까 말씀드렸던 로그 스키마 변경입니다.
로그 스키마 변경
• 이미 쌓인 로그에 대하여 마이그레이션 불가능
• 오직 컬럼 추가만 가능
쉽게 스키마를 추가할 수 있고
로그 스키마 변경
• 이미 쌓인 로그에 대하여 마이그레이션 불가능
• 오직 컬럼 추가만 가능
컬럼 추가도 자유롭지만
로그 스키마 변경
• 이미 쌓인 로그에 대하여 마이그레이션 불가능
• 오직 컬럼 추가만 가능
컬럼 이름을 바꿀 수 없다는 것이
로그 스키마 변경
• 이미 쌓인 로그에 대하여 마이그레이션 불가능
• 오직 컬럼 추가만 가능
의외로 시간이 지나면서
불편을 초래하고 있습니다.
“이 컬럼은 정확히 뭘 의미하나요?”
• 100개가 넘는 스키마, 모두 기억하지 못함
• 문서가 없기 때문에 발생하는 현상
마지막으로 컨텐츠가 추가되거나
“이 컬럼은 정확히 뭘 의미하나요?”
• 100개가 넘는 스키마, 모두 기억하지 못함
• 문서가 없기 때문에 발생하는 현상
남겨야 할 정보들이 더 많아지고 하면서
“이 컬럼은 정확히 뭘 의미하나요?”
• 100개가 넘는 스키마, 모두 기억하지 못함
• 문서가 없기 때문에 발생하는 현상
스키마 개수도 100개가 넘고
“이 컬럼은 정확히 뭘 의미하나요?”
• 100개가 넘는 스키마, 모두 기억하지 못함
• 문서가 없기 때문에 발생하는 현상
컬럼도 계속 추가되고 있는데요.
“이 컬럼은 정확히 뭘 의미하나요?”
• 100개가 넘는 스키마, 모두 기억하지 못함
• 문서가 없기 때문에 발생하는 현상
어떤 컬럼이 정확히 무엇을 의미하는 지에 대해
“이 컬럼은 정확히 뭘 의미하나요?”
• 100개가 넘는 스키마, 모두 기억하지 못함
• 문서가 없기 때문에 발생하는 현상
직접 코드를 보아야 알 수 있는 경우도 있었습니다.
“이 컬럼은 정확히 뭘 의미하나요?”
• 100개가 넘는 스키마, 모두 기억하지 못함
• 문서가 없기 때문에 발생하는 현상
이 것은 결국 문서가 없기 때문에 발생하는 현상인데요.
“이 컬럼은 정확히 뭘 의미하나요?”
• 100개가 넘는 스키마, 모두 기억하지 못함
• 문서가 없기 때문에 발생하는 현상
→ Docstring을 이용한 스키마 문서화?
스키마 별로 클래스를 정의하고 있기 때문에
“이 컬럼은 정확히 뭘 의미하나요?”
• 100개가 넘는 스키마, 모두 기억하지 못함
• 문서가 없기 때문에 발생하는 현상
→ Docstring을 이용한 스키마 문서화?
Docstring을 이용해서
스키마를 문서화하는 방법을 고안 중입니다.
감사합니다
네, 제가 준비한 내용은 여기까지인데요.
감사합니다
많은 것을 공유하고 싶었고
감사합니다
때문에 많은 내용을 다루다 보니
감사합니다
조금 지루할 수도 있고
미처 자세히 설명하지 못한 부분도 있을 수 있지만
감사합니다
여기까지 들어주신 분들께 감사드립니다.
만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
김찬웅 님 / 4월 25일 오후 4시 30분
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
이흥섭 님 / 4월 25일 오후 3시 20분
〈야생의 땅: 듀랑고〉 NoSQL 위에서 MMORPG 개발하기
최호영 님 / 4월 26일 오전 11시
듀랑고의 서버에 관련된 발표로
만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
김찬웅 님 / 4월 25일 오후 4시 30분
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
이흥섭 님 / 4월 25일 오후 3시 20분
〈야생의 땅: 듀랑고〉 NoSQL 위에서 MMORPG 개발하기
최호영 님 / 4월 26일 오전 11시
내일과 내일 모레에도 세션들이 준비되어있으니
만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
김찬웅 님 / 4월 25일 오후 4시 30분
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
이흥섭 님 / 4월 25일 오후 3시 20분
〈야생의 땅: 듀랑고〉 NoSQL 위에서 MMORPG 개발하기
최호영 님 / 4월 26일 오전 11시
관심있는 분들은 많은 참석바랍니다.
WE'RE HIRING!http://what.studio/
마지막으로 저희 왓 스튜디오는
다양한 직군에 대해서 채용을 진행하고 있으니
WE'RE HIRING!http://what.studio/
많은 관심 부탁드립니다.
WE'RE HIRING!http://what.studio/
이상으로 발표를 마치겠습니다. 감사합니다.

Weitere ähnliche Inhalte

Was ist angesagt?

[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기Chanwoong Kim
 
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912Yooseok Choi
 
[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영NAVER D2
 
쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기Brian Hong
 
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장Dylan Ko
 
스타트업 나홀로 데이터 엔지니어: 데이터 분석 환경 구축기 - 천지은 (Tappytoon) :: AWS Community Day Onlin...
스타트업 나홀로 데이터 엔지니어: 데이터 분석 환경 구축기 - 천지은 (Tappytoon) :: AWS Community Day Onlin...스타트업 나홀로 데이터 엔지니어: 데이터 분석 환경 구축기 - 천지은 (Tappytoon) :: AWS Community Day Onlin...
스타트업 나홀로 데이터 엔지니어: 데이터 분석 환경 구축기 - 천지은 (Tappytoon) :: AWS Community Day Onlin...AWSKRUG - AWS한국사용자모임
 
How to build massive service for advance
How to build massive service for advanceHow to build massive service for advance
How to build massive service for advanceDaeMyung Kang
 
인공지능추천시스템 airs개발기_모델링과시스템
인공지능추천시스템 airs개발기_모델링과시스템인공지능추천시스템 airs개발기_모델링과시스템
인공지능추천시스템 airs개발기_모델링과시스템NAVER D2
 
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라Seongyun Byeon
 
Data Engineering 101
Data Engineering 101Data Engineering 101
Data Engineering 101DaeMyung Kang
 
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?Juhong Park
 
데이터가 흐르는 조직 만들기 - 마이리얼트립
데이터가 흐르는 조직 만들기 - 마이리얼트립데이터가 흐르는 조직 만들기 - 마이리얼트립
데이터가 흐르는 조직 만들기 - 마이리얼트립승화 양
 
트위터의 추천 시스템 파헤치기
트위터의 추천 시스템 파헤치기트위터의 추천 시스템 파헤치기
트위터의 추천 시스템 파헤치기Yan So
 
데브시스터즈 데이터 레이크 구축 이야기 : Data Lake architecture case study (박주홍 데이터 분석 및 인프라 팀...
데브시스터즈 데이터 레이크 구축 이야기 : Data Lake architecture case study (박주홍 데이터 분석 및 인프라 팀...데브시스터즈 데이터 레이크 구축 이야기 : Data Lake architecture case study (박주홍 데이터 분석 및 인프라 팀...
데브시스터즈 데이터 레이크 구축 이야기 : Data Lake architecture case study (박주홍 데이터 분석 및 인프라 팀...Amazon Web Services Korea
 
[261] 실시간 추천엔진 머신한대에 구겨넣기
[261] 실시간 추천엔진 머신한대에 구겨넣기[261] 실시간 추천엔진 머신한대에 구겨넣기
[261] 실시간 추천엔진 머신한대에 구겨넣기NAVER D2
 
커머스 스타트업의 효율적인 데이터 분석 플랫폼 구축기 - 하지양 데이터 엔지니어, 발란 / 강웅석 데이터 엔지니어, 크로키닷컴 :: AWS...
커머스 스타트업의 효율적인 데이터 분석 플랫폼 구축기 - 하지양 데이터 엔지니어, 발란 / 강웅석 데이터 엔지니어, 크로키닷컴 :: AWS...커머스 스타트업의 효율적인 데이터 분석 플랫폼 구축기 - 하지양 데이터 엔지니어, 발란 / 강웅석 데이터 엔지니어, 크로키닷컴 :: AWS...
커머스 스타트업의 효율적인 데이터 분석 플랫폼 구축기 - 하지양 데이터 엔지니어, 발란 / 강웅석 데이터 엔지니어, 크로키닷컴 :: AWS...Amazon Web Services Korea
 
4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴Terry Cho
 
[215]네이버콘텐츠통계서비스소개 김기영
[215]네이버콘텐츠통계서비스소개 김기영[215]네이버콘텐츠통계서비스소개 김기영
[215]네이버콘텐츠통계서비스소개 김기영NAVER D2
 
Airflow를 이용한 데이터 Workflow 관리
Airflow를 이용한  데이터 Workflow 관리Airflow를 이용한  데이터 Workflow 관리
Airflow를 이용한 데이터 Workflow 관리YoungHeon (Roy) Kim
 
[DevGround] 린하게 구축하는 스타트업 데이터파이프라인
[DevGround] 린하게 구축하는 스타트업 데이터파이프라인[DevGround] 린하게 구축하는 스타트업 데이터파이프라인
[DevGround] 린하게 구축하는 스타트업 데이터파이프라인Jae Young Park
 

Was ist angesagt? (20)

[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
[NDC18] 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기
 
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1  나무기술(주) 최유석 20170912
Bigquery와 airflow를 이용한 데이터 분석 시스템 구축 v1 나무기술(주) 최유석 20170912
 
[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영[236] 카카오의데이터파이프라인 윤도영
[236] 카카오의데이터파이프라인 윤도영
 
쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기쿠키런 1년, 서버개발 분투기
쿠키런 1년, 서버개발 분투기
 
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
[우리가 데이터를 쓰는 법] 모바일 게임 로그 데이터 분석 이야기 - 엔터메이트 공신배 팀장
 
스타트업 나홀로 데이터 엔지니어: 데이터 분석 환경 구축기 - 천지은 (Tappytoon) :: AWS Community Day Onlin...
스타트업 나홀로 데이터 엔지니어: 데이터 분석 환경 구축기 - 천지은 (Tappytoon) :: AWS Community Day Onlin...스타트업 나홀로 데이터 엔지니어: 데이터 분석 환경 구축기 - 천지은 (Tappytoon) :: AWS Community Day Onlin...
스타트업 나홀로 데이터 엔지니어: 데이터 분석 환경 구축기 - 천지은 (Tappytoon) :: AWS Community Day Onlin...
 
How to build massive service for advance
How to build massive service for advanceHow to build massive service for advance
How to build massive service for advance
 
인공지능추천시스템 airs개발기_모델링과시스템
인공지능추천시스템 airs개발기_모델링과시스템인공지능추천시스템 airs개발기_모델링과시스템
인공지능추천시스템 airs개발기_모델링과시스템
 
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라Little Big Data #1. 바닥부터 시작하는 데이터 인프라
Little Big Data #1. 바닥부터 시작하는 데이터 인프라
 
Data Engineering 101
Data Engineering 101Data Engineering 101
Data Engineering 101
 
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
[KAIST 채용설명회] 데이터 엔지니어는 무슨 일을 하나요?
 
데이터가 흐르는 조직 만들기 - 마이리얼트립
데이터가 흐르는 조직 만들기 - 마이리얼트립데이터가 흐르는 조직 만들기 - 마이리얼트립
데이터가 흐르는 조직 만들기 - 마이리얼트립
 
트위터의 추천 시스템 파헤치기
트위터의 추천 시스템 파헤치기트위터의 추천 시스템 파헤치기
트위터의 추천 시스템 파헤치기
 
데브시스터즈 데이터 레이크 구축 이야기 : Data Lake architecture case study (박주홍 데이터 분석 및 인프라 팀...
데브시스터즈 데이터 레이크 구축 이야기 : Data Lake architecture case study (박주홍 데이터 분석 및 인프라 팀...데브시스터즈 데이터 레이크 구축 이야기 : Data Lake architecture case study (박주홍 데이터 분석 및 인프라 팀...
데브시스터즈 데이터 레이크 구축 이야기 : Data Lake architecture case study (박주홍 데이터 분석 및 인프라 팀...
 
[261] 실시간 추천엔진 머신한대에 구겨넣기
[261] 실시간 추천엔진 머신한대에 구겨넣기[261] 실시간 추천엔진 머신한대에 구겨넣기
[261] 실시간 추천엔진 머신한대에 구겨넣기
 
커머스 스타트업의 효율적인 데이터 분석 플랫폼 구축기 - 하지양 데이터 엔지니어, 발란 / 강웅석 데이터 엔지니어, 크로키닷컴 :: AWS...
커머스 스타트업의 효율적인 데이터 분석 플랫폼 구축기 - 하지양 데이터 엔지니어, 발란 / 강웅석 데이터 엔지니어, 크로키닷컴 :: AWS...커머스 스타트업의 효율적인 데이터 분석 플랫폼 구축기 - 하지양 데이터 엔지니어, 발란 / 강웅석 데이터 엔지니어, 크로키닷컴 :: AWS...
커머스 스타트업의 효율적인 데이터 분석 플랫폼 구축기 - 하지양 데이터 엔지니어, 발란 / 강웅석 데이터 엔지니어, 크로키닷컴 :: AWS...
 
4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴
 
[215]네이버콘텐츠통계서비스소개 김기영
[215]네이버콘텐츠통계서비스소개 김기영[215]네이버콘텐츠통계서비스소개 김기영
[215]네이버콘텐츠통계서비스소개 김기영
 
Airflow를 이용한 데이터 Workflow 관리
Airflow를 이용한  데이터 Workflow 관리Airflow를 이용한  데이터 Workflow 관리
Airflow를 이용한 데이터 Workflow 관리
 
[DevGround] 린하게 구축하는 스타트업 데이터파이프라인
[DevGround] 린하게 구축하는 스타트업 데이터파이프라인[DevGround] 린하게 구축하는 스타트업 데이터파이프라인
[DevGround] 린하게 구축하는 스타트업 데이터파이프라인
 

Ähnlich wie [NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)

관계형 데이터베이스의 새로운 패러다임 Amazon Aurora :: 김상필 :: AWS Summit Seoul 2016
관계형 데이터베이스의 새로운 패러다임 Amazon Aurora :: 김상필 :: AWS Summit Seoul 2016관계형 데이터베이스의 새로운 패러다임 Amazon Aurora :: 김상필 :: AWS Summit Seoul 2016
관계형 데이터베이스의 새로운 패러다임 Amazon Aurora :: 김상필 :: AWS Summit Seoul 2016Amazon Web Services Korea
 
AWS 9월 웨비나 | Amazon Aurora Deep Dive
AWS 9월 웨비나 | Amazon Aurora Deep DiveAWS 9월 웨비나 | Amazon Aurora Deep Dive
AWS 9월 웨비나 | Amazon Aurora Deep DiveAmazon Web Services Korea
 
AWS의 하둡 관련 서비스 - EMR/S3
AWS의 하둡 관련 서비스 - EMR/S3AWS의 하둡 관련 서비스 - EMR/S3
AWS의 하둡 관련 서비스 - EMR/S3Keeyong Han
 
Amazon Aurora Deep Dive (김기완) - AWS DB Day
Amazon Aurora Deep Dive (김기완) - AWS DB DayAmazon Aurora Deep Dive (김기완) - AWS DB Day
Amazon Aurora Deep Dive (김기완) - AWS DB DayAmazon Web Services Korea
 
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)Amazon Web Services Korea
 
천만사용자를 위한 AWS 클라우드 아키텍처 진화하기 – 문종민, AWS솔루션즈 아키텍트:: AWS Summit Online Korea 2020
천만사용자를 위한 AWS 클라우드 아키텍처 진화하기 – 문종민, AWS솔루션즈 아키텍트::  AWS Summit Online Korea 2020천만사용자를 위한 AWS 클라우드 아키텍처 진화하기 – 문종민, AWS솔루션즈 아키텍트::  AWS Summit Online Korea 2020
천만사용자를 위한 AWS 클라우드 아키텍처 진화하기 – 문종민, AWS솔루션즈 아키텍트:: AWS Summit Online Korea 2020Amazon Web Services Korea
 
AWS EMR Cost optimization
AWS EMR Cost optimizationAWS EMR Cost optimization
AWS EMR Cost optimizationSANG WON PARK
 
게임 서비스를 위한 AWS상의 고성능 SQL 데이터베이스 구성 (이정훈 솔루션즈 아키텍트, AWS) :: Gaming on AWS 2018
게임 서비스를 위한 AWS상의 고성능 SQL 데이터베이스 구성 (이정훈 솔루션즈 아키텍트, AWS) :: Gaming on AWS 2018게임 서비스를 위한 AWS상의 고성능 SQL 데이터베이스 구성 (이정훈 솔루션즈 아키텍트, AWS) :: Gaming on AWS 2018
게임 서비스를 위한 AWS상의 고성능 SQL 데이터베이스 구성 (이정훈 솔루션즈 아키텍트, AWS) :: Gaming on AWS 2018Amazon Web Services Korea
 
Spark streaming tutorial
Spark streaming tutorialSpark streaming tutorial
Spark streaming tutorialMinho Kim
 
Spark overview 이상훈(SK C&C)_스파크 사용자 모임_20141106
Spark overview 이상훈(SK C&C)_스파크 사용자 모임_20141106Spark overview 이상훈(SK C&C)_스파크 사용자 모임_20141106
Spark overview 이상훈(SK C&C)_스파크 사용자 모임_20141106SangHoon Lee
 
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?nexusz99
 
AWS를 통한 빅데이터 기반 비지니스 인텔리전스 구축- AWS Summit Seoul 2017
AWS를 통한 빅데이터 기반 비지니스 인텔리전스 구축- AWS Summit Seoul 2017AWS를 통한 빅데이터 기반 비지니스 인텔리전스 구축- AWS Summit Seoul 2017
AWS를 통한 빅데이터 기반 비지니스 인텔리전스 구축- AWS Summit Seoul 2017Amazon Web Services Korea
 
넥슨레드 RF실과 함께할 개발자를 찾습니다
넥슨레드 RF실과 함께할 개발자를 찾습니다넥슨레드 RF실과 함께할 개발자를 찾습니다
넥슨레드 RF실과 함께할 개발자를 찾습니다NEXON RED
 
spark database Service
spark database Servicespark database Service
spark database Service창언 정
 
게임 고객 사례를 통해 살펴보는 AWS 활용 전략 :: 이경안 :: AWS Summit Seoul 2016
게임 고객 사례를 통해 살펴보는 AWS 활용 전략 :: 이경안 :: AWS Summit Seoul 2016게임 고객 사례를 통해 살펴보는 AWS 활용 전략 :: 이경안 :: AWS Summit Seoul 2016
게임 고객 사례를 통해 살펴보는 AWS 활용 전략 :: 이경안 :: AWS Summit Seoul 2016Amazon Web Services Korea
 
Amazon Aurora 성능 향상 및 마이그레이션 모범 사례 - AWS Summit Seoul 2017
Amazon Aurora 성능 향상 및 마이그레이션 모범 사례 - AWS Summit Seoul 2017Amazon Aurora 성능 향상 및 마이그레이션 모범 사례 - AWS Summit Seoul 2017
Amazon Aurora 성능 향상 및 마이그레이션 모범 사례 - AWS Summit Seoul 2017Amazon Web Services Korea
 
AWS에 대해 궁금했던 10가지 질문들(윤석찬) - AWS 웨비나 시리즈 2015
AWS에 대해 궁금했던 10가지 질문들(윤석찬) - AWS 웨비나 시리즈 2015AWS에 대해 궁금했던 10가지 질문들(윤석찬) - AWS 웨비나 시리즈 2015
AWS에 대해 궁금했던 10가지 질문들(윤석찬) - AWS 웨비나 시리즈 2015Amazon Web Services Korea
 
AWSKRUG DS - 데이터 엔지니어가 실무에서 맞닥뜨리는 문제들
AWSKRUG DS - 데이터 엔지니어가 실무에서 맞닥뜨리는 문제들AWSKRUG DS - 데이터 엔지니어가 실무에서 맞닥뜨리는 문제들
AWSKRUG DS - 데이터 엔지니어가 실무에서 맞닥뜨리는 문제들Woong Seok Kang
 

Ähnlich wie [NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부) (20)

관계형 데이터베이스의 새로운 패러다임 Amazon Aurora :: 김상필 :: AWS Summit Seoul 2016
관계형 데이터베이스의 새로운 패러다임 Amazon Aurora :: 김상필 :: AWS Summit Seoul 2016관계형 데이터베이스의 새로운 패러다임 Amazon Aurora :: 김상필 :: AWS Summit Seoul 2016
관계형 데이터베이스의 새로운 패러다임 Amazon Aurora :: 김상필 :: AWS Summit Seoul 2016
 
AWS 9월 웨비나 | Amazon Aurora Deep Dive
AWS 9월 웨비나 | Amazon Aurora Deep DiveAWS 9월 웨비나 | Amazon Aurora Deep Dive
AWS 9월 웨비나 | Amazon Aurora Deep Dive
 
Amazon Aurora 100% 활용하기
Amazon Aurora 100% 활용하기Amazon Aurora 100% 활용하기
Amazon Aurora 100% 활용하기
 
AWS의 하둡 관련 서비스 - EMR/S3
AWS의 하둡 관련 서비스 - EMR/S3AWS의 하둡 관련 서비스 - EMR/S3
AWS의 하둡 관련 서비스 - EMR/S3
 
Amazon Aurora Deep Dive (김기완) - AWS DB Day
Amazon Aurora Deep Dive (김기완) - AWS DB DayAmazon Aurora Deep Dive (김기완) - AWS DB Day
Amazon Aurora Deep Dive (김기완) - AWS DB Day
 
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
AWS 6월 웨비나 | AWS에서 MS SQL 서버 운영하기 (김민성 솔루션즈아키텍트)
 
천만사용자를 위한 AWS 클라우드 아키텍처 진화하기 – 문종민, AWS솔루션즈 아키텍트:: AWS Summit Online Korea 2020
천만사용자를 위한 AWS 클라우드 아키텍처 진화하기 – 문종민, AWS솔루션즈 아키텍트::  AWS Summit Online Korea 2020천만사용자를 위한 AWS 클라우드 아키텍처 진화하기 – 문종민, AWS솔루션즈 아키텍트::  AWS Summit Online Korea 2020
천만사용자를 위한 AWS 클라우드 아키텍처 진화하기 – 문종민, AWS솔루션즈 아키텍트:: AWS Summit Online Korea 2020
 
AWS EMR Cost optimization
AWS EMR Cost optimizationAWS EMR Cost optimization
AWS EMR Cost optimization
 
게임 서비스를 위한 AWS상의 고성능 SQL 데이터베이스 구성 (이정훈 솔루션즈 아키텍트, AWS) :: Gaming on AWS 2018
게임 서비스를 위한 AWS상의 고성능 SQL 데이터베이스 구성 (이정훈 솔루션즈 아키텍트, AWS) :: Gaming on AWS 2018게임 서비스를 위한 AWS상의 고성능 SQL 데이터베이스 구성 (이정훈 솔루션즈 아키텍트, AWS) :: Gaming on AWS 2018
게임 서비스를 위한 AWS상의 고성능 SQL 데이터베이스 구성 (이정훈 솔루션즈 아키텍트, AWS) :: Gaming on AWS 2018
 
Spark streaming tutorial
Spark streaming tutorialSpark streaming tutorial
Spark streaming tutorial
 
Spark overview 이상훈(SK C&C)_스파크 사용자 모임_20141106
Spark overview 이상훈(SK C&C)_스파크 사용자 모임_20141106Spark overview 이상훈(SK C&C)_스파크 사용자 모임_20141106
Spark overview 이상훈(SK C&C)_스파크 사용자 모임_20141106
 
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
Dropbox와 같은 시스템은 파일을 어떻게 저장할까?
 
AWS를 통한 빅데이터 기반 비지니스 인텔리전스 구축- AWS Summit Seoul 2017
AWS를 통한 빅데이터 기반 비지니스 인텔리전스 구축- AWS Summit Seoul 2017AWS를 통한 빅데이터 기반 비지니스 인텔리전스 구축- AWS Summit Seoul 2017
AWS를 통한 빅데이터 기반 비지니스 인텔리전스 구축- AWS Summit Seoul 2017
 
넥슨레드 RF실과 함께할 개발자를 찾습니다
넥슨레드 RF실과 함께할 개발자를 찾습니다넥슨레드 RF실과 함께할 개발자를 찾습니다
넥슨레드 RF실과 함께할 개발자를 찾습니다
 
spark database Service
spark database Servicespark database Service
spark database Service
 
AWS 약쟁이
AWS 약쟁이AWS 약쟁이
AWS 약쟁이
 
게임 고객 사례를 통해 살펴보는 AWS 활용 전략 :: 이경안 :: AWS Summit Seoul 2016
게임 고객 사례를 통해 살펴보는 AWS 활용 전략 :: 이경안 :: AWS Summit Seoul 2016게임 고객 사례를 통해 살펴보는 AWS 활용 전략 :: 이경안 :: AWS Summit Seoul 2016
게임 고객 사례를 통해 살펴보는 AWS 활용 전략 :: 이경안 :: AWS Summit Seoul 2016
 
Amazon Aurora 성능 향상 및 마이그레이션 모범 사례 - AWS Summit Seoul 2017
Amazon Aurora 성능 향상 및 마이그레이션 모범 사례 - AWS Summit Seoul 2017Amazon Aurora 성능 향상 및 마이그레이션 모범 사례 - AWS Summit Seoul 2017
Amazon Aurora 성능 향상 및 마이그레이션 모범 사례 - AWS Summit Seoul 2017
 
AWS에 대해 궁금했던 10가지 질문들(윤석찬) - AWS 웨비나 시리즈 2015
AWS에 대해 궁금했던 10가지 질문들(윤석찬) - AWS 웨비나 시리즈 2015AWS에 대해 궁금했던 10가지 질문들(윤석찬) - AWS 웨비나 시리즈 2015
AWS에 대해 궁금했던 10가지 질문들(윤석찬) - AWS 웨비나 시리즈 2015
 
AWSKRUG DS - 데이터 엔지니어가 실무에서 맞닥뜨리는 문제들
AWSKRUG DS - 데이터 엔지니어가 실무에서 맞닥뜨리는 문제들AWSKRUG DS - 데이터 엔지니어가 실무에서 맞닥뜨리는 문제들
AWSKRUG DS - 데이터 엔지니어가 실무에서 맞닥뜨리는 문제들
 

[NDC18] 야생의 땅 듀랑고의 데이터 엔지니어링 이야기: 로그 시스템 구축 경험 공유 (2부)

  • 1. 〈야생의 땅: 듀랑고〉의 데이터 엔지니어링 이야기 넥슨 컴퍼니 왓 스튜디오 전효준 : 로그 시스템 구축 경험 공유 2부
  • 2. SlideShare에 슬라이드 300장 제한으로 부득이하게 2부로 나누어 올렸습니다. 현재 보고 계신 슬라이드는 2부입니다.
  • 3. 분석 마지막으로 이렇게 S3에 적재한 로그를 분석하는 단계인데요.
  • 4. 분석 클러스터 S3 ZeppelinSpark AWS EMR DataPipeline 전체적으로 Apache Spark와 Apache Zeppelin을 사용하고 있습니다.
  • 5. 분석 클러스터 S3 ZeppelinSpark AWS EMR 클러스터 컴퓨팅 엔진 DataPipeline Apache Spark는 클러스터 컴퓨팅 엔진으로
  • 6. 분석 클러스터 S3 ZeppelinSpark AWS EMR 대화식 인터프리터 + 쉬운 시각화 DataPipeline Zeppelin은 이런 Spark를 대화식 인터프리터에서 사용하게 해주고
  • 7. 분석 클러스터 S3 ZeppelinSpark AWS EMR 대화식 인터프리터 + 쉬운 시각화 DataPipeline 결과를 시각화하는 용도로 사용하고 있고요.
  • 8. 분석 클러스터 S3 ZeppelinSpark AWS EMR 클러스터 구성 DataPipeline 이러한 Spark와 Zeppelin의 클러스터를 구성하는 데에
  • 9. 분석 클러스터 S3 ZeppelinSpark AWS EMR 클러스터 구성 DataPipeline EMR이라는 서비스를 사용하고 있습니다.
  • 10. 분석 클러스터 S3 ZeppelinSpark AWS EMR DataPipeline 배치잡 구성 그리고 여기 옆에 DataPipeline은 배치잡을 구성하는 데 사용하고있습니다.
  • 11. ZeppelinSpark AWS EMR 먼저 Spark와 Zeppelin, 그리고 이것을 구성하는 EMR에 대해서 말씀드리려고 합니다.
  • 12. • 클러스터 컴퓨팅 엔진 • • Python, Scala, R, Java 언어지원 • 다양한 모듈 지원 (SparkSQL, MLlib 등) Apache Spark Spark 인 메모리 데이터 처리 Apache Spark는 클러스터 컴퓨팅 엔진인데요.
  • 13. • 클러스터 컴퓨팅 엔진 • • Python, Scala, R, Java 언어지원 • 다양한 모듈 지원 (SparkSQL, MLlib 등) Apache Spark Spark 인 메모리 데이터 처리 → 빠르다! 이전에 Hadoop에서 디스크 기반으로 수행하던 MapReduce 작업을
  • 14. • 클러스터 컴퓨팅 엔진 • • Python, Scala, R, Java 언어지원 • 다양한 모듈 지원 (SparkSQL, MLlib 등) Apache Spark Spark 인 메모리 데이터 처리 → 빠르다! Spark에서는 메모리에서 처리하기 때문에
  • 15. • 클러스터 컴퓨팅 엔진 • • Python, Scala, R, Java 언어지원 • 다양한 모듈 지원 (SparkSQL, MLlib 등) Apache Spark Spark 인 메모리 데이터 처리 → 빠르다! 빠른 속도라는 장점을 가지고 있습니다.
  • 16. • 클러스터 컴퓨팅 엔진 • • Python, Scala, R, Java 언어지원 • 다양한 모듈 지원 (SparkSQL, MLlib 등) Apache Spark Spark 인 메모리 데이터 처리 → 빠르다! 다양한 언어를 지원하기도 하고
  • 17. • 클러스터 컴퓨팅 엔진 • • Python, Scala, R, Java 언어지원 • 다양한 모듈 지원 (SparkSQL, MLlib 등) Apache Spark Spark 인 메모리 데이터 처리 → 빠르다! 데이터에 대하여 SQL을 사용할 수 있는 SparkSQL 모듈과
  • 18. • 클러스터 컴퓨팅 엔진 • • Python, Scala, R, Java 언어지원 • 다양한 모듈 지원 (SparkSQL, MLlib 등) Apache Spark Spark 인 메모리 데이터 처리 → 빠르다! 머신러닝 라이브러리, 스트리밍 모듈 등 여러가지 모듈을 지원하는데
  • 19. • 클러스터 컴퓨팅 엔진 • • Python, Scala, R, Java 언어지원 • 다양한 모듈 지원 (SparkSQL, MLlib 등) Apache Spark Spark 인 메모리 데이터 처리 → 빠르다! 클러스터 컴퓨팅 엔진이라고 소개해 드리긴 했지만
  • 20. • 클러스터 컴퓨팅 엔진 • • Python, Scala, R, Java 언어지원 • 다양한 모듈 지원 (SparkSQL, MLlib 등) Apache Spark Spark 인 메모리 데이터 처리 → 빠르다! 범용 분산 플랫폼이 맞는 표현입니다.
  • 21. df = spark.read.json('logs.json') over_21 = df.where('age >= 21').count() 보고 계신 코드는 Spark에서 JSON 포맷의 로그를 읽고
  • 22. df = spark.read.json('logs.json') over_21 = df.where('age >= 21').count() 나이가 21세 이상인 사람들에 대한 로그를 카운트하는 예제입니다.
  • 23. df = spark.read.json('logs.json') over_21 = df.where('age >= 21').count() Spark에서 저희가 주로 사용하는 데이터 프레임이라는 데이터 구조를 사용한 코드인데요.
  • 24. df = spark.read.json('logs.json') over_21 = df.where('age >= 21').count() 실제로 보시는 바와 같이 쉽게 사용할 수 있습니다.
  • 25. • • 다양한 인터프리터 사용가능 • 쉬운 시각화 Apache Zeppelin Zeppelin 대화식 분석이 가능한 웹 기반 노트북 다음으로는 이런 Spark 사용을 쉽게해주는 Apache Zeppelin입니다.
  • 26. • • 다양한 인터프리터 사용가능 • 쉬운 시각화 Apache Zeppelin Zeppelin 대화식 분석이 가능한 웹 기반 노트북 대화식 분석이 가능하기 때문에
  • 27. • • 다양한 인터프리터 사용가능 • 쉬운 시각화 Apache Zeppelin Zeppelin 대화식 분석이 가능한 웹 기반 노트북 파이썬으로 데이터 분석하시는 분들께서 많이 사용하시는 Jupyter notebook 처럼
  • 28. • • 다양한 인터프리터 사용가능 • 쉬운 시각화 Apache Zeppelin Zeppelin 대화식 분석이 가능한 웹 기반 노트북 파라미터를 바꿔가면서 결과를 보면서 작업을 이어갈 수 있고
  • 29. • • 다양한 인터프리터 사용가능 • 쉬운 시각화 Apache Zeppelin → Spark! Zeppelin 대화식 분석이 가능한 웹 기반 노트북 다양한 인터프리터를 사용할 수 있기 때문에
  • 30. • • 다양한 인터프리터 사용가능 • 쉬운 시각화 Apache Zeppelin → Spark! Zeppelin 대화식 분석이 가능한 웹 기반 노트북 Spark 인터프리터부터, 각종 언어들, JDBC 등 여러 가지를 연동하여 사용할 수 있습니다.
  • 31. • • 다양한 인터프리터 사용가능 • 쉬운 시각화 Apache Zeppelin → Spark! Zeppelin 대화식 분석이 가능한 웹 기반 노트북 마지막으로 가장 유용하다고 생각하는 기능 중 하나인 시각화인데요.
  • 32. • • 다양한 인터프리터 사용가능 • 쉬운 시각화 Apache Zeppelin → Spark! Zeppelin 대화식 분석이 가능한 웹 기반 노트북 별다른 처리 없이도 결과에 따라서 잘 알아서 시각화를 해줍니다.
  • 33. SparkSQL 보시는 것은 실제 Zeppelin의 사용 모습입니다.
  • 34. SparkSQL 이렇게 Spark SQL 쿼리로 분석할 수 있고 (쿼리 내용 중요하지 않음)
  • 35. 다이나믹 폼 사용가능 실제 쿼리의 조건절에 들어가는 값을 다양하게 바꿀 수 있는 다이나믹 폼도 지원합니다.
  • 36. 다양한 그래프 또한, 단순 테이블, 막대 그래프, 파이 그래프 등 여러 가지 그래프를 지원하고요.
  • 37. CSV 다운로드 결과를 CSV로 다운로드할 수 있습니다.
  • 38. 스케줄링 그리고 노트북을 특정 시간대에 자동으로 실행하도록
  • 40. 스케줄링 보시는 바와 같이 Cron Expression으로 자동실행 스케줄을 지정할 수 있습니다.
  • 41. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR 이렇게 Apache Spark와 Apache Zeppelin의 클러스터를 구성하는 데에는
  • 42. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR AWS의 EMR 서비스를 사용하고 있습니다.
  • 43. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin Spark 클러스터를 클릭 몇 번으로 쉽게 구성가능하고
  • 44. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 여기에 Zeppelin도 같이 구성할 수 있습니다.
  • 45. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 게다가 AWS에서 유휴자원을 싼 가격에 사용할 수 있는
  • 46. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 스팟 인스턴스도 사용가능한데요.
  • 47. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 도쿄 리전 r4.4xlarge 기준으로 4분의 1가격에 사용가능합니다.
  • 48. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 또한 쉽게 확장 및 축소가 가능하다는 것도 장점입니다.
  • 49. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 10개 인스턴스로 5분 1개 인스턴스로 50분 아주 단순하게 생각했을 때
  • 50. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 10개 인스턴스로 5분 1개 인스턴스로 50분 10개 인스턴스로 5분동안 처리하는 것과
  • 51. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 10개 인스턴스로 5분 1개 인스턴스로 50분 1개 인스턴스로 50분동안 처리하는 것이
  • 52. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 10개 인스턴스로 5분 1개 인스턴스로 50분 비용 만약 같은 비용이라면
  • 53. • Spark 클러스터를 손쉽게 구성 • 스팟 인스턴스 사용가능 • 쉬운 확장 및 축소 AWS EMR EMR + Zeppelin 10개 인스턴스로 5분 1개 인스턴스로 50분 비용 당연히 많은 인스턴스로 짧은 시간 동안 처리하는 게 훨씬 이득이겠죠.
  • 54. 정기적인 배치 잡은 어떻게 실행하나요? 하지만 정기적으로 필요한 분석을 위한 배치잡은 어떻게 실행하는 지 궁금하실 수 있는데요.
  • 55. Zeppelin의 노트북 스케줄 기능 ? 여기서 아까 보셨던 Zeppelin의 노트북 스케줄 기능을 생각하실 수 있습니다.
  • 56. Zeppelin의 노트북 스케줄 기능 ? 실패 시 자동 재시도 완료 시 클러스터 반납 하지만 Zeppelin은 실패시 자동으로 재시도하거나
  • 57. Zeppelin의 노트북 스케줄 기능 ? 실패 시 자동 재시도 완료 시 클러스터 반납 완료 시 인스턴스를 반납하는 것과 같은 동작은 할 수 없기 때문에
  • 58. Zeppelin의 노트북 스케줄 기능 ? 실패 시 자동 재시도 완료 시 클러스터 반납 Ad-hoc 분석용으로만 사용 저희는 Zeppelin을 Ad-hoc 분석용으로만 사용하고 있습니다.
  • 59. DataPipeline 그 대안으로 AWS의 DataPipeline이라는 서비스를 사용하고 있습니다.
  • 60. 보시는 것은 DataPipeline 서비스를 AWS 콘솔에서 봤을 때의 모습인데요.
  • 64. 매일 00시에 클러스터를 실행하고 특정 Job을 수행해라특정 Job을 수행해라라는 의미인데요.
  • 65. 매일 00시에 클러스터를 실행하고 특정 Job을 수행해라실제로 Job이 실패했을 때 재시도하거나
  • 66. 매일 00시에 클러스터를 실행하고 특정 Job을 수행해라실행이 끝났을 때 클러스터를 모두 종료할 수 있기 때문에
  • 67. 매일 00시에 클러스터를 실행하고 특정 Job을 수행해라비용을 절감할 수 있습니다.
  • 68. 분석 클러스터 S3 ZeppelinSpark AWS EMR DataPipeline 이렇게 저희의 분석 클러스터가 어떻게 구성되었는지 말씀드렸는데요.
  • 69. 분석 클러스터 S3 ZeppelinSpark AWS EMR DataPipeline 마지막으로 전체 아키텍처를 정리를 해보면
  • 71. S3Lambda ZeppelinSpark AWS EMR DataPipeline 게임 서버 Fluentd Lambda Kinesis ES 5초 이내 1. 로그를 확인하기 까지 로그를 확인하는 데 까지 5초 이내로 확인할 수 있고
  • 72. S3Lambda Lambda ES ZeppelinSpark AWS EMR DataPipeline 게임 서버 Fluentd 2. 로그 유입량이 증가하면? Kinesis 확장 포인트 만약 로그 유입량이 증가하더라도
  • 73. S3Lambda Lambda ES ZeppelinSpark AWS EMR DataPipeline 게임 서버 Fluentd 2. 로그 유입량이 증가하면? Kinesis 확장 포인트 Kinesis의 샤드 개수만 증가시키면 됩니다.
  • 74. S3Lambda Lambda ES ZeppelinSpark AWS EMR DataPipeline 게임 서버 Fluentd 2. 로그 유입량이 증가하면? Kinesis 확장 포인트 아, Fluentd는 저희 같은 경우 아까 말씀드렸다시피
  • 75. S3Lambda Lambda ES ZeppelinSpark AWS EMR DataPipeline 게임 서버 Fluentd 2. 로그 유입량이 증가하면? Kinesis 확장 포인트 각각의 호스트에 하나씩 존재하므로 호스트 개수만큼 알아서 확장하는 구조입니다.
  • 76. • 도쿄 리전 기준 • 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도) • Kinesis 샤드 2개 + 데이터 PUT 비용 • Lambda (처리시간 1초) → 약 $90 → 약 $20 3. Kinesis + Lambda 월 유지비용 → 월 $110 정도로 유지 비용(저장비용 제외)
  • 77. • 도쿄 리전 기준 • 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도) • Kinesis 샤드 2개 + 데이터 PUT 비용 • Lambda (처리시간 1초) → 약 $90 → 약 $20 3. Kinesis + Lambda 월 유지비용 → 월 $110 정도로 유지 비용(저장비용 제외) 여기서 잠시 로그 수집 파이프라인의 비용을 살펴보면
  • 78. • 도쿄 리전 기준 • 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도) • Kinesis 샤드 2개 + 데이터 PUT 비용 • Lambda (처리시간 1초) → 약 $90 → 약 $20 3. Kinesis + Lambda 월 유지비용 → 월 $110 정도로 유지 비용(저장비용 제외) 만약에 초당 1000개의 로그가 지속적으로 유입되고
  • 79. • 도쿄 리전 기준 • 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도) • Kinesis 샤드 2개 + 데이터 PUT 비용 • Lambda (처리시간 1초) → 약 $90 → 약 $20 3. Kinesis + Lambda 월 유지비용 → 월 $110 정도로 유지 비용(저장비용 제외) 초당 2MB정도 유입된다고 가정하면
  • 80. • 도쿄 리전 기준 • 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도) • Kinesis 샤드 2개 + 데이터 PUT 비용 • Lambda (처리시간 1초) → 약 $90 → 약 $20 3. Kinesis + Lambda 월 유지비용 → 월 $110 정도로 유지 비용(저장비용 제외) 월 5TB정도의 로그가 발생하는데요.
  • 81. • 도쿄 리전 기준 • 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도) • Kinesis 샤드 2개 + 데이터 PUT 비용 • Lambda (처리시간 1초) → 약 $90 → 약 $20 3. Kinesis + Lambda 월 유지비용 → 월 $110 정도로 유지 비용(저장비용 제외) 이 때 최소로 필요한 Kinesis 샤드 2개와
  • 82. • 도쿄 리전 기준 • 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도) • Kinesis 샤드 2개 + 데이터 PUT 비용 • Lambda (처리시간 1초) → 약 $90 → 약 $20 3. Kinesis + Lambda 월 유지비용 → 월 $110 정도로 유지 비용(저장비용 제외)데이터를 기록하는 비용, Lambda에서 처리하는 비용을 모두 합쳐도
  • 83. • 도쿄 리전 기준 • 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도) • Kinesis 샤드 2개 + 데이터 PUT 비용 • Lambda (처리시간 1초) → 약 $90 → 약 $20 3. Kinesis + Lambda 월 유지비용 → 월 $110 정도로 유지 비용(저장비용 제외) 월 110달러 정도의 유지 비용이 발생합니다.
  • 84. • 도쿄 리전 기준 • 초당 1000개 로그 유입, 각 로그는 2KB(월 5TB 정도) • Kinesis 샤드 2개 + 데이터 PUT 비용 • Lambda (처리시간 1초) → 약 $90 → 약 $20 3. Kinesis + Lambda 월 유지비용 → 월 $110 정도로 유지 비용(저장비용 제외)물론 이건 저장비용을 제외하고, 최소로 맞춘 스펙이니 참고만 부탁드립니다.
  • 85. 게임 서버 Fluentd S3Lambda Lambda Kinesis ES DataPipeline 4. 빠르게 분석하고 싶을 때 확장 포인트 ZeppelinSpark AWS EMR 분석을 빠르게 하고 싶을 때는
  • 86. 게임 서버 Fluentd S3Lambda Lambda Kinesis ES DataPipeline 4. 빠르게 분석하고 싶을 때 확장 포인트 ZeppelinSpark AWS EMR EMR 클러스터만 확장해주면 됩니다.
  • 87. 5. 대규모 분석 비용 • 모든 로그에 대하여 • r4.8xlarge X 10 스팟 인스턴스, 도쿄 리전 기준 • 생성된 모든 섬의 개수 • 가장 많이 채집된 자원(10위까지) • 모든 섬의 날짜별 일일 활성 유저수 → 5분 = $1 미만 → 10분 = 약$1 → 15분 = 약 $ 1.3 프로비저닝 시간 제외, 2018년 4월 24일 기준 만약 대규모 분석을 위해서
  • 88. 5. 대규모 분석 비용 • 모든 로그에 대하여 • r4.8xlarge X 10 스팟 인스턴스, 도쿄 리전 기준 • 생성된 모든 섬의 개수 • 가장 많이 채집된 자원(10위까지) • 모든 섬의 날짜별 일일 활성 유저수 → 5분 = $1 미만 → 10분 = 약$1 → 15분 = 약 $ 1.3 프로비저닝 시간 제외, 2018년 4월 24일 기준 도쿄 리전을 기준으로 r4.8xlarge 타입의 인스턴스를 스팟 인스턴스로 10개를 띄우고
  • 89. 5. 대규모 분석 비용 • 모든 로그에 대하여 • r4.8xlarge X 10 스팟 인스턴스, 도쿄 리전 기준 • 생성된 모든 섬의 개수 • 가장 많이 채집된 자원(10위까지) • 모든 섬의 날짜별 일일 활성 유저수 → 5분 = $1 미만 → 10분 = 약$1 → 15분 = 약 $ 1.3 프로비저닝 시간 제외, 2018년 4월 24일 기준 분석이 끝나는 즉시 종료한다면
  • 90. 5. 대규모 분석 비용 • 모든 로그에 대하여 • r4.8xlarge X 10 스팟 인스턴스, 도쿄 리전 기준 • 생성된 모든 섬의 개수 • 가장 많이 채집된 자원(10위까지) • 모든 섬의 날짜별 일일 활성 유저수 → 5분 = $1 미만 → 10분 = 약$1 → 15분 = 약 $ 1.3 프로비저닝 시간 제외, 2018년 4월 24일 기준 보시는 바와 같이 시간과 비용을 최대한 절감할 수 있습니다.
  • 91. #4 ‘잘’ 사용하기 다음으로는 이런 아키텍처에서
  • 92. #4 ‘잘’ 사용하기 각각의 구성요소들을 잘 사용하기 위한 방법들을 말씀드리려고 합니다.
  • 93. 게임 서버 Fluentd S3Lambda Lambda ES ZeppelinSpark AWS EMR DataPipeline Kinesis 확장 포인트 Kinesis 샤드 개수는 어떻게 결정하나요? 첫 번째로, 방금 로그 유입량이 늘어나면
  • 94. 게임 서버 Fluentd S3Lambda Lambda ES ZeppelinSpark AWS EMR DataPipeline Kinesis 확장 포인트 Kinesis 샤드 개수는 어떻게 결정하나요? Kinesis의 샤드개수를 늘리면 된다고 말씀드렸는데요.
  • 95. • 샤드의 처리량 제한 • Lambda의 처리속도 Kinesis 샤드 개수는 어떻게 결정하나요? 사실 이 Kinesis 샤드 개수를 결정하기 위해
  • 96. • 샤드의 처리량 제한 • Lambda의 처리속도 Kinesis 샤드 개수는 어떻게 결정하나요? 고려해야 할 두 가지가 있습니다.
  • 97. Kinesis 샤드 개수는 어떻게 결정하나요? • 샤드의 처리량 제한 • Lambda의 처리속도 샤드 하나에 초당 처리할 수 있는 처리량 제한이 있고요.
  • 98. Kinesis 샤드 개수는 어떻게 결정하나요? • 샤드의 처리량 제한 • Lambda의 처리속도 또한 Lambda의 처리속도를 고려해야합니다.
  • 99. Lambda Iterator age 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 이 그래프는 Lambda의 Iterator age라는 메트릭입니다.
  • 100. Lambda Iterator age 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 Lambda가 가장 최근에 처리한 레코드의
  • 101. Lambda Iterator age 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 Kinesis에 실제로 처음 기록된 시간과
  • 102. Lambda Iterator age 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 Lambda가 이 레코드를 처리하기 위해 이벤트를 받은
  • 103. Lambda Iterator age 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 시간 차이인데요.
  • 104. Lambda Iterator age 증가하면 안됨 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 결국 Kinesis에 데이터가 들어오는 속도보다
  • 105. Lambda Iterator age 증가하면 안됨 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 Lambda의 처리속도가 느리면
  • 106. Lambda Iterator age 증가하면 안됨 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 메트릭이 계속 상승곡선을 이루게 됩니다.
  • 107. Lambda Iterator age 증가하면 안됨 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 여기서 Lambda는 이벤트가 일어나는 만큼 자동으로 확장하지 않느냐?라고 생각하실 수 있는데요.
  • 108. Lambda Iterator age 증가하면 안됨 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 Lambda를 일반적인 사용예인 API형태로 사용할 때와 Kinesis를 트리거할 때는
  • 109. Lambda Iterator age 증가하면 안됨 가장 최근에 처리한 레코드가 Kinesis에 기록된 시간과 Lambda가 레코드를 받은 시간차이 다른 동작 형태를 보입니다.
  • 110. Shard 1 Kinesis Lambda Shard 2 Shard 3 예를 들어 Kinesis에 3개의 샤드가 존재하고
  • 111. Shard 1 Kinesis Lambda Shard 2 Shard 3 Lambda가 이를 트리거한다고 가정해보겠습니다.
  • 112. Shard 1 Kinesis Lambda Shard 2 Shard 3 보통은 Kinesis의 샤드에는 랜덤하게 데이터가 분배되는데
  • 113. Shard 1 Kinesis Lambda Shard 2 Shard 3 데이터가 1번 샤드에 하나 들어오면
  • 114. Shard 1 Kinesis Lambda Shard 2 Shard 3 ! Lambda는 “아! 이번 샤드에 데이터가 들어왔구나!”하고
  • 115. Shard 1 Kinesis Lambda Shard 2 Shard 3 ! 이 것을 처리하려고 하는데요.
  • 116. Shard 1 Kinesis Lambda Shard 2 Shard 3 이때 Lambda는 1번 샤드의 데이터를 처리합니다.
  • 117. Shard 1 Kinesis Lambda Shard 2 Shard 3 만약에 모든 데이터가 다 처리되면
  • 118. Shard 1 Kinesis Lambda Shard 2 Shard 3 더 이상 Lambda가 실행되지 않고요.
  • 119. Shard 1 Kinesis Lambda Shard 2 Shard 3 물론 여기서 데이터를 처리하더라도
  • 120. Shard 1 Kinesis Lambda Shard 2 Shard 3 Kinesis에 데이터는 계속 보존되는데
  • 121. Shard 1 Kinesis Lambda Shard 2 Shard 3 그림에서는 이해를 돕기 위해 없앴습니다.
  • 122. Shard 1 Kinesis Lambda Shard 2 Shard 3 그리고 다시 3번 샤드에 데이터가 들어오면
  • 123. Shard 1 Kinesis Lambda Shard 2 Shard 3 다시 이것을 처리하게 되겠죠.
  • 124. Shard 1 Kinesis Lambda Shard 2 Shard 3 만약 3개의 샤드에 동시에 데이터가 들어오면
  • 125. Shard 1 Kinesis Lambda Shard 2 Shard 3 Lambda는 3개 샤드만큼 동시실행하여
  • 126. Shard 1 Kinesis Lambda Shard 2 Shard 3 각각의 샤드에 대해서 처리하게 됩니다.
  • 127. Shard 1 Kinesis Lambda Shard 2 Shard 3 1초 마다 배치 처리 만약 지속적으로 데이터가 들어오는 상황에서는
  • 128. Shard 1 Kinesis Lambda Shard 2 Shard 3 1초 마다 배치 처리 각각의 샤드에 대해서 1초마다 동기적으로 배치처리를 하게 됩니다.
  • 129. Shard 1 Kinesis Lambda Shard 2 Shard 3 1초 마다 배치 처리 샤드 개수 증가 Lambda 동시실행 결국 Lambda는 최대 Kinesis의 샤드개수만큼
  • 130. Shard 1 Kinesis Lambda Shard 2 Shard 3 1초 마다 배치 처리 샤드 개수 증가 Lambda 동시실행 동시실행이 될 수 있기 때문에
  • 131. Shard 1 Kinesis Lambda Shard 2 Shard 3 1초 마다 배치 처리 샤드 개수 증가 Lambda 동시실행 Kinesis의 샤드 개수를 증가시키는 것은
  • 132. Shard 1 Kinesis Lambda Shard 2 Shard 3 1초 마다 배치 처리 샤드 개수 증가 Lambda 동시실행 Lambda의 동시실행 수를 높일 수 있다는 것을 의미합니다.
  • 133. Kinesis – Lambda 처리속도를 높이는 방법 1. Kinesis stream의 샤드 개수를 증가시킨다. 2. Lambda의 가용 메모리를 증가시킨다. (Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨) 여기서 Lambda의 처리속도를 높이는 방법을 정리해보면
  • 134. Kinesis – Lambda 처리속도를 높이는 방법 1. Kinesis stream의 샤드 개수를 증가시킨다. 2. Lambda의 가용 메모리를 증가시킨다. (Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨) Kinesis의 샤드 개수를 증가시켜서 Lambda의 동시 실행 수를 늘리는 방법이 있고
  • 135. Kinesis – Lambda 처리속도를 높이는 방법 1. Kinesis stream의 샤드 개수를 증가시킨다. 2. Lambda의 가용 메모리를 증가시킨다. (Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨) Lambda는 설정된 메모리 크기에 따라
  • 136. Kinesis – Lambda 처리속도를 높이는 방법 1. Kinesis stream의 샤드 개수를 증가시킨다. 2. Lambda의 가용 메모리를 증가시킨다. (Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨) CPU 성능이 조절되기 때문에
  • 137. Kinesis – Lambda 처리속도를 높이는 방법 1. Kinesis stream의 샤드 개수를 증가시킨다. 2. Lambda의 가용 메모리를 증가시킨다. (Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨) Lambda의 가용 메모리를 증가시켜서 CPU 성능을 높이는 방법이 있습니다.
  • 138. Kinesis – Lambda 처리속도를 높이는 방법 1. Kinesis stream의 샤드 개수를 증가시킨다. 2. Lambda의 가용 메모리를 증가시킨다. (Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨) 하지만 저희의 경우 CPU 보다는
  • 139. Kinesis – Lambda 처리속도를 높이는 방법 1. Kinesis stream의 샤드 개수를 증가시킨다. 2. Lambda의 가용 메모리를 증가시킨다. (Lambda는 가용 메모리 크기에 따라 CPU 성능이 조절됨) I/O에 인텐시브하기 때문에 두 번째 방법은 배제하고 있습니다.
  • 140. 로그파일 포맷: JSON • 복잡한 게임 시스템 → 복잡한 로그 스키마 • Lambda는 최대 1000개의 로그를 하나의 파일로 저장 (Kinesis 샤드의 초당 최대 쓰기 개수) 이제 저희가 로그를 어떻게 저장하는 지 말씀드리려고 합니다.
  • 141. 로그파일 포맷: JSON • 복잡한 게임 시스템 → 복잡한 로그 스키마 • Lambda는 최대 1000개의 로그를 하나의 파일로 저장 (Kinesis 샤드의 초당 최대 쓰기 개수) 저희는 아이템 구조 등 복잡한 게임시스템으로
  • 142. 로그파일 포맷: JSON • 복잡한 게임 시스템 → 복잡한 로그 스키마 • Lambda는 최대 1000개의 로그를 하나의 파일로 저장 (Kinesis 샤드의 초당 최대 쓰기 개수) 보다 유연한 로그 스키마가 필요했고
  • 143. 로그파일 포맷: JSON • 복잡한 게임 시스템 → 복잡한 로그 스키마 • Lambda는 최대 1000개의 로그를 하나의 파일로 저장 (Kinesis 샤드의 초당 최대 쓰기 개수) 때문에 JSON 형식으로 로그를 저장하고 있습니다.
  • 144. 로그파일 포맷: JSON • 복잡한 게임 시스템 → 복잡한 로그 스키마 • Lambda는 최대 1000개의 로그를 하나의 파일로 저장 (Kinesis 샤드의 초당 최대 쓰기 개수) 여기서 Lambda는 최대 1000개의 로그를 하나의 파일로 저장하는데요.
  • 145. 엄청나게 많은 파일 개수 → 네트워크 오버헤드 로그파일 포맷: JSON • 복잡한 게임 시스템 → 복잡한 로그 스키마 • Lambda는 최대 1000개의 로그를 하나의 파일로 저장 (Kinesis 샤드의 초당 최대 쓰기 개수) 사실 이런 저장방식은 엄청나게 많은 파일을 생성시키고
  • 146. 엄청나게 많은 파일 개수 → 네트워크 오버헤드 로그파일 포맷: JSON • 복잡한 게임 시스템 → 복잡한 로그 스키마 • Lambda는 최대 1000개의 로그를 하나의 파일로 저장 (Kinesis 샤드의 초당 최대 쓰기 개수) 결국 분석 시에 네트워크 오버헤드를 유발하게 됩니다.
  • 147. JSON → Parquet 때문에 저희는 JSON을 Parquet 형식의 파일로 가공하는데요.
  • 148. JSON → Parquet 많은 수의 파일을 단지 몇 개로 분할된 Parquet 파일로 변환하고 있고
  • 149. JSON → Parquet 이런 변환을 1시간 마다 배치잡으로 처리하고 있습니다.
  • 151. Parquet 이런 중첩 데이터 구조를 모두 지원하면서도
  • 152. Parquet 구조화된 형태를 가지는 Parquet 포맷으로 변환하게됩니다.
  • 153. Parquet • 스키마를 가진 컬럼형 저장 포맷 • 복잡한 중첩 데이터 구조도 지원 • 기본적으로 Snappy 압축 • Column projection • Predicate pushdown Parquet 파일 형식에 대해서 소개해드리면
  • 154. Parquet • 스키마를 가진 컬럼형 저장 포맷 • 복잡한 중첩 데이터 구조도 지원 • 기본적으로 Snappy 압축 • Column projection • Predicate pushdown 먼저 스키마를 가진 컬럼형 저장 포맷이라고 말씀드릴 수 있습니다.
  • 155. Parquet • 스키마를 가진 컬럼형 저장 포맷 • 복잡한 중첩 데이터 구조도 지원 • 기본적으로 Snappy 압축 • Column projection • Predicate pushdown 또한 구조화된 포맷임에도 불구하고
  • 156. Parquet • 스키마를 가진 컬럼형 저장 포맷 • 복잡한 중첩 데이터 구조도 지원 • 기본적으로 Snappy 압축 • Column projection • Predicate pushdown 복잡한 중첩데이터 구조도 지원하고요.
  • 157. Parquet → 네트워크 트래픽 감소 • 스키마를 가진 컬럼형 저장 포맷 • 복잡한 중첩 데이터 구조도 지원 • 기본적으로 Snappy 압축 • Column projection • Predicate pushdown 기본적으로 Snappy 형식의 압축을 하고있고
  • 158. Parquet → 네트워크 트래픽 감소 • 스키마를 가진 컬럼형 저장 포맷 • 복잡한 중첩 데이터 구조도 지원 • 기본적으로 Snappy 압축 • Column projection • Predicate pushdown Column projection, Predicate Pushdown 기능을 제공합니다.
  • 159. Parquet → 네트워크 트래픽 감소 • 스키마를 가진 컬럼형 저장 포맷 • 복잡한 중첩 데이터 구조도 지원 • 기본적으로 Snappy 압축 • Column projection • Predicate pushdown Snappy 압축과 아래 두가지 기능은
  • 160. Parquet → 네트워크 트래픽 감소 • 스키마를 가진 컬럼형 저장 포맷 • 복잡한 중첩 데이터 구조도 지원 • 기본적으로 Snappy 압축 • Column projection • Predicate pushdown 네트워크 트래픽을 감소 시킬 수 있습니다.
  • 161. Column projection 이 Column projection에 대해서 간단히 설명을 드리면
  • 162. Column projection 4월 1일에 접속한 레벨 60의 플레이어 수 SELECT COUNT(DISTINCT(player_entity_id)) FROM PlayerEntered_asia_a WHERE __date="2018-04-01" AND player_level=60 4월 1일에 접속한 레벨 60의 플레이어 수를 추출하는 쿼리를 예제로 들 수 있습니다.
  • 163. Column projection 쿼리에 필요한 컬럼만 스캔 +- *FileScan parquet [player_entity_id#44,player_level#45,__date#53] 이 쿼리의 플랜을 보면
  • 164. Column projection 쿼리에 필요한 컬럼만 스캔 +- *FileScan parquet [player_entity_id#44,player_level#45,__date#53] 쿼리에 실제로 필요한 플레이어 아이디와, 레벨, 날짜만 스캔하는 것을 알 수 있습니다.
  • 165. Column projection 쿼리에 필요한 컬럼만 스캔 +- *FileScan parquet [player_entity_id#44,player_level#45,__date#53] 결국 컬럼형 저장방식이기 때문에
  • 166. Column projection 쿼리에 필요한 컬럼만 스캔 +- *FileScan parquet [player_entity_id#44,player_level#45,__date#53] 쿼리에 필요한 컬럼만 스캔하여
  • 167. Column projection 쿼리에 필요한 컬럼만 스캔 +- *FileScan parquet [player_entity_id#44,player_level#45,__date#53] 네트워크 트래픽을 낮출 수 있습니다.
  • 168. Predicate pushdown 레벨 60인 데이터만 필터링 PushedFilteres: [IsNotNull(player_level), EqualTo(player_level,60)] 또 Predicate pushdown은 같은 예제로
  • 169. Predicate pushdown 레벨 60인 데이터만 필터링 PushedFilteres: [IsNotNull(player_level), EqualTo(player_level,60)] 메타데이터에 저장된 통계값을 이용해
  • 170. Predicate pushdown 레벨 60인 데이터만 필터링 PushedFilteres: [IsNotNull(player_level), EqualTo(player_level,60)] 레벨이 60인 데이터만 필터링하여 스캔합니다.
  • 171. Predicate pushdownColumn projection 이렇게 Column Projection과 Predicate pushdown을 활용하여
  • 172. Predicate pushdownColumn projection 최대한 필요한 데이터만 읽도록 하여
  • 173. Predicate pushdownColumn projection 네트워크 트래픽을 낮출 수 있는데요.
  • 174. Table Partitioning • 데이터 스캔 범위를 제한가능 • 저장경로에 '<key>=<value>' 형태로 분리 여기에 테이블 파티셔닝이라는 기능을 이용하면
  • 175. Table Partitioning → 네트워크 트래픽 감소• 데이터 스캔 범위를 제한가능 • 저장경로에 '<key>=<value>' 형태로 분리 추가적으로 네트워크 트래픽을 감소시킬 수 있습니다.
  • 176. Table Partitioning s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename> → 네트워크 트래픽 감소• 데이터 스캔 범위를 제한가능 • 저장경로에 '<key>=<value>' 형태로 분리 여러 가지 방법이 있긴 하지만
  • 177. Table Partitioning s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename> → 네트워크 트래픽 감소• 데이터 스캔 범위를 제한가능 • 저장경로에 '<key>=<value>' 형태로 분리 저장경로에 Key=Value 형태로 중간 경로를 지정하는 형태로 사용할 수 있습니다.
  • 178. Table Partitioning s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename> → 네트워크 트래픽 감소• 데이터 스캔 범위를 제한가능 • 저장경로에 '<key>=<value>' 형태로 분리 실제로 저희는 날짜별로 파티셔닝을 하고 있는데
  • 179. Table Partitioning SELECT COUNT(DISTINCT(player_entity_id)) FROM PlayerEntered_asia_a WHERE __date="2018-04-01" AND player_level=60 아까와 같이 4월 1일에 접속한 레벨이 60인 플레이어 수를 구하는 예제에서
  • 180. SELECT COUNT(DISTINCT(player_entity_id)) FROM PlayerEntered_asia_a WHERE __date="2018-04-01" AND player_level=60 실제 컬럼처럼 사용가능 Table Partitioning WHERE __date="2018-04-01" s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename> 아까 저장경로 상에서 지정한 date라는 파티션을
  • 181. SELECT COUNT(DISTINCT(player_entity_id)) FROM PlayerEntered_asia_a WHERE __date="2018-04-01" AND player_level=60 실제 컬럼처럼 사용가능 Table Partitioning WHERE __date="2018-04-01" s3://<bucket>/<schema>/__date=<yyyy-mm-dd>/<filename> 실제 컬럼처럼 사용가능하고요.
  • 182. SELECT COUNT(DISTINCT(player_entity_id)) FROM PlayerEntered_asia_a WHERE __date="2018-04-01" AND player_level=60 쿼리 플랜에서 동작을 확인할 수 있다. Table Partitioning PartitionFilters: [isnotnull(__date#53), (cast(__date#53as string)=2018-04-01)] 쿼리플랜에서도 다음과 같이 파티션 필터가 동작하면서
  • 183. SELECT COUNT(DISTINCT(player_entity_id)) FROM PlayerEntered_asia_a WHERE __date="2018-04-01" AND player_level=60 쿼리 플랜에서 동작을 확인할 수 있다. Table Partitioning PartitionFilters: [isnotnull(__date#53), (cast(__date#53as string)=2018-04-01)] date가 4월 1일인 파티션을 필터링하는 것을 볼 수 있습니다.
  • 184. SELECT COUNT(DISTINCT(player_entity_id)) FROM PlayerEntered_asia_a WHERE __date="2018-04-01" AND player_level=60 쿼리 플랜에서 동작을 확인할 수 있다. Table Partitioning PartitionFilters: [isnotnull(__date#53), (cast(__date#53as string)=2018-04-01)] 실제로 해당되는 파티션의 데이터만 S3에서 읽기 때문에
  • 185. SELECT COUNT(DISTINCT(player_entity_id)) FROM PlayerEntered_asia_a WHERE __date="2018-04-01" AND player_level=60 쿼리 플랜에서 동작을 확인할 수 있다. Table Partitioning PartitionFilters: [isnotnull(__date#53), (cast(__date#53as string)=2018-04-01)] 훨씬 네트워크 트래픽을 감소시킬 수 있습니다.
  • 186. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 다음은 로그 스키마 관리인데요.
  • 187. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 결국은 JSON에서 Parquet로 구조화된 데이터 유형을 사용하기 때문에
  • 188. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 로그 스키마 관리가 필요합니다.
  • 189. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 먼저 저희는 접속로그, 채집로그 등
  • 190. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 로그 유형별로 스키마를 가지고 있습니다.
  • 191. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 새롭게 컨텐츠가 들어갈 때 새로운 스키마를 쉽게 추가할 수 있지만
  • 192. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 기존에 존재하는 스키마를 변경할 땐
  • 193. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 약간 제한되는 것들이 있습니다.
  • 194. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 약간 제한되는 것들이 있습니다.
  • 195. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 예를 들어, 컬럼 이름을 바꾼다고 하면
  • 196. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 이미 적재되어 있는 모든 로그에 대하여
  • 197. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. 새로운 컬럼 이름으로 바꿔서 다시 저장하는 마이그레이션 비용이 매우 크기 때문입니다.
  • 198. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. → 컬럼 추가만 가능! 하위호환성을 유지하여야 한다. 때문에 저희는 컬럼 추가만 가능하게 하여
  • 199. 로그 스키마 관리 • 로그는 다양한 스키마를 가진다. • 접속로그, 채집로그, 구매로그 등 • 새로운 스키마는 언제든지 추가될 수 있어야 한다. • 스키마 변경 시 적재된 로그를 모두 마이그레이션할 수 없다. → 컬럼 추가만 가능! 하위호환성을 유지하여야 한다. 하위호환성을 유지하는 정책을 두고 있습니다.
  • 200. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 저희는 서버 코드 상에서 로그 스키마를 관리하는데요.
  • 201. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 스키마 별로 클래스가 존재하고
  • 202. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 이 클래스로부터 데이터를 담은 객체를 생성하여 로그를 전송합니다.
  • 203. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 새로운 버전 배포 시에
  • 204. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 각각의 스키마 별로
  • 205. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 SparkSQL에서 StructType이라는 클래스에서 다루는 JSON 포맷으로 스키마를 추출하고
  • 206. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 이 것을 따로 특정 S3 버킷에 저장합니다.
  • 207. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 그리고 JSON 파일을 Parquet로 변환하는 배치잡에서는
  • 208. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 아까 저장했던 스키마 중 가장 최근 버전의 스키마를 읽고 처리하는데요.
  • 209. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 스키마 저장소를 따로 관리하기 때문에
  • 210. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 새로 추가된 스키마에 대해서도
  • 211. 로그 스키마 업데이트 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 별다른 처리 없이 배치잡에서 알 수 있습니다.
  • 212. 로그 스키마 업데이트 schema = StructType.fromJson(schema_json) Parquet 변환 시 로드 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 PySpark
  • 213. 로그 스키마 업데이트 schema = StructType.fromJson(schema_json) Parquet 변환 시 로드 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 PySpark JSON으로된 로그를 Parquet로 변환시
  • 214. 로그 스키마 업데이트 schema = StructType.fromJson(schema_json) Parquet 변환 시 로드 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 PySpark 보시는 코드와 같이 JSON으로된 스키마 파일을 로드하여
  • 215. 로그 스키마 업데이트 schema = StructType.fromJson(schema_json) Parquet 변환 시 로드 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 PySpark StructType 객체를 생성하고
  • 216. 로그 스키마 업데이트 schema = StructType.fromJson(schema_json) Parquet 변환 시 로드 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 PySpark JSON 로그의 스키마를 지정하고 있습니다.
  • 217. 로그 스키마 업데이트 schema = StructType.fromJson(schema_json) Parquet 변환 시 로드 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 PySpark 물론 JSON 로그로 부터 스키마를 추론할 수 있기도 하지만
  • 218. 로그 스키마 업데이트 schema = StructType.fromJson(schema_json) Parquet 변환 시 로드 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 PySpark 성능이 느려지고
  • 219. 로그 스키마 업데이트 schema = StructType.fromJson(schema_json) Parquet 변환 시 로드 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 PySpark 명시적인 것이 훨씬 좋다는 판단 하에
  • 220. 로그 스키마 업데이트 schema = StructType.fromJson(schema_json) Parquet 변환 시 로드 1. 스키마 별 Class 추가 또는 업데이트 2. 배포 시 Spark StructType JSON 포맷으로 추출 3. AWS S3에 저장 4. Parquet 변환 배치잡에서 매번 스키마 정보를 읽고 수행 PySpark 스키마를 따로 정의하고 관리하는 방법을 사용하고 있습니다.
  • 221. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 다음으로는 EMR에서 Spark 클러스터를 할당하는 팁인데요.
  • 222. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 인 메모리 방식이기 때문에 많은 메모리가 필요할 수 있어서
  • 223. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 메모리 최적화 타입인 r4 타입을 선호하고 있습니다.
  • 224. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 또한 작은 인스턴스 여러 개 보다는
  • 225. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 큰 인스턴스 하나를 사용하고 있는데
  • 226. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 그 이유는 좋은 인스턴스일수록
  • 227. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 AWS에서 더 높은 네트워크 속도를 제공하고 있고
  • 228. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 EMR에서 Spark를 사용할 때
  • 229. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 YARN이라는 리소스 매니저를 사용하는데
  • 230. EMR Spark 클러스터 스펙 • 메모리가 중요하므로 r4 타입을 선호 • 작은 인스턴스 4개 보다 큰 인스턴스 1개로 • 좋은 인스턴스가 네트워크 속도도 더 빠르다 • EMR이 YARN 컨테이너에 할당하는 메모리 비율이 더 크다 이 때 YARN 컨테이너에 할당하는 메모리 비율이 더 크기 때문입니다.
  • 231. #5 개선할 점 네, 여기까지 저희 로그 시스템에 대한 소개를 마쳤습니다.
  • 232. #5 개선할 점 그래서 결론이 “완벽한 로그 시스템인가?” 에 대하여
  • 233. #5 개선할 점 실제 운영결과, 앞서 말했던 목표를 달성하였지만
  • 234. #5 개선할 점 몇 가지 분명 불편한 점이 있었습니다.
  • 235. #5 개선할 점 마지막으로 개선할 점을 말씀드리면서 정리를 하고자합니다.
  • 236. • 분석가는 언제나 부족 • 비 개발자도 분석하기도 쉬웠으면 • SQL은 과연 쉬운가…? • 사실상 대중화 실패 • 하는 사람만 한다. 분석의 대중화 먼저 분석의 대중화가 어려웠습니다.
  • 237. • 분석가는 언제나 부족 • 비 개발자도 분석하기도 쉬웠으면 • SQL은 과연 쉬운가…? • 사실상 대중화 실패 • 하는 사람만 한다. 분석의 대중화 분석에 대한 수요는 많지만 분석가는 언제나 부족합니다.
  • 238. • 분석가는 언제나 부족 • 비 개발자도 분석하기도 쉬웠으면 • SQL은 과연 쉬운가…? • 사실상 대중화 실패 • 하는 사람만 한다. 분석의 대중화 때문에 비 개발자도 분석하기 쉬웠으면 이라는 생각도 하는데요.
  • 239. • 분석가는 언제나 부족 • 비 개발자도 분석하기도 쉬웠으면 • SQL은 과연 쉬운가…? • 사실상 대중화 실패 • 하는 사람만 한다. 분석의 대중화 사실 이런 점을 위해서 나름 간단한 분석은 쉽게 할 수 있도록
  • 240. • 분석가는 언제나 부족 • 비 개발자도 분석하기도 쉬웠으면 • SQL은 과연 쉬운가…? • 사실상 대중화 실패 • 하는 사람만 한다. 분석의 대중화 SQL을 사용할 수 있는 것을 목표로 하였습니다만
  • 241. • 분석가는 언제나 부족 • 비 개발자도 분석하기도 쉬웠으면 • SQL은 과연 쉬운가…? • 사실상 대중화 실패 • 하는 사람만 한다. 분석의 대중화 사실상 대중화는 쉽지 않았습니다.
  • 242. • 분석의 규모에 따라 • 클러스터 크기가 자동으로 조절되었으면 분석 규모에 따른 오토 스케일링 또한 분석 규모에 따라 오토 스케일링이 되었으면 좋겠다라는 생각을 했습니다.
  • 243. • 분석의 규모에 따라 • 클러스터 크기가 자동으로 조절되었으면 분석 규모에 따른 오토 스케일링 비용을 좀 더 효과적으로 절감하고
  • 244. • 분석의 규모에 따라 • 클러스터 크기가 자동으로 조절되었으면 분석 규모에 따른 오토 스케일링 시간을 효율적으로 사용할 수 있었으면 하는 바람이 있습니다.
  • 245. 시각화의 다양화 • 한편으로는 복잡한 시각화가 필요할 때도 있다. • Zeppelin으로는 아직 제한적 한편으로는 Zeppelin에만 시각화에 대한 상당부분을 의존하고 있기 때문에
  • 246. 시각화의 다양화 • 한편으로는 복잡한 시각화가 필요할 때도 있다. • Zeppelin으로는 아직 제한적 복잡한 시각화의 경우
  • 247. 시각화의 다양화 • 한편으로는 복잡한 시각화가 필요할 때도 있다. • Zeppelin으로는 아직 제한적 Jupyter notebook에서 따로 시각화하고 있는데요.
  • 248. 시각화의 다양화 • 한편으로는 복잡한 시각화가 필요할 때도 있다. • Zeppelin으로는 아직 제한적 이 부분도 아직은 아쉬움으로 남고 있습니다.
  • 249. 로그 스키마 변경 • 이미 쌓인 로그에 대하여 마이그레이션 불가능 • 오직 컬럼 추가만 가능 세 번째는 아까 말씀드렸던 로그 스키마 변경입니다.
  • 250. 로그 스키마 변경 • 이미 쌓인 로그에 대하여 마이그레이션 불가능 • 오직 컬럼 추가만 가능 쉽게 스키마를 추가할 수 있고
  • 251. 로그 스키마 변경 • 이미 쌓인 로그에 대하여 마이그레이션 불가능 • 오직 컬럼 추가만 가능 컬럼 추가도 자유롭지만
  • 252. 로그 스키마 변경 • 이미 쌓인 로그에 대하여 마이그레이션 불가능 • 오직 컬럼 추가만 가능 컬럼 이름을 바꿀 수 없다는 것이
  • 253. 로그 스키마 변경 • 이미 쌓인 로그에 대하여 마이그레이션 불가능 • 오직 컬럼 추가만 가능 의외로 시간이 지나면서 불편을 초래하고 있습니다.
  • 254. “이 컬럼은 정확히 뭘 의미하나요?” • 100개가 넘는 스키마, 모두 기억하지 못함 • 문서가 없기 때문에 발생하는 현상 마지막으로 컨텐츠가 추가되거나
  • 255. “이 컬럼은 정확히 뭘 의미하나요?” • 100개가 넘는 스키마, 모두 기억하지 못함 • 문서가 없기 때문에 발생하는 현상 남겨야 할 정보들이 더 많아지고 하면서
  • 256. “이 컬럼은 정확히 뭘 의미하나요?” • 100개가 넘는 스키마, 모두 기억하지 못함 • 문서가 없기 때문에 발생하는 현상 스키마 개수도 100개가 넘고
  • 257. “이 컬럼은 정확히 뭘 의미하나요?” • 100개가 넘는 스키마, 모두 기억하지 못함 • 문서가 없기 때문에 발생하는 현상 컬럼도 계속 추가되고 있는데요.
  • 258. “이 컬럼은 정확히 뭘 의미하나요?” • 100개가 넘는 스키마, 모두 기억하지 못함 • 문서가 없기 때문에 발생하는 현상 어떤 컬럼이 정확히 무엇을 의미하는 지에 대해
  • 259. “이 컬럼은 정확히 뭘 의미하나요?” • 100개가 넘는 스키마, 모두 기억하지 못함 • 문서가 없기 때문에 발생하는 현상 직접 코드를 보아야 알 수 있는 경우도 있었습니다.
  • 260. “이 컬럼은 정확히 뭘 의미하나요?” • 100개가 넘는 스키마, 모두 기억하지 못함 • 문서가 없기 때문에 발생하는 현상 이 것은 결국 문서가 없기 때문에 발생하는 현상인데요.
  • 261. “이 컬럼은 정확히 뭘 의미하나요?” • 100개가 넘는 스키마, 모두 기억하지 못함 • 문서가 없기 때문에 발생하는 현상 → Docstring을 이용한 스키마 문서화? 스키마 별로 클래스를 정의하고 있기 때문에
  • 262. “이 컬럼은 정확히 뭘 의미하나요?” • 100개가 넘는 스키마, 모두 기억하지 못함 • 문서가 없기 때문에 발생하는 현상 → Docstring을 이용한 스키마 문서화? Docstring을 이용해서 스키마를 문서화하는 방법을 고안 중입니다.
  • 263. 감사합니다 네, 제가 준비한 내용은 여기까지인데요.
  • 266. 감사합니다 조금 지루할 수도 있고 미처 자세히 설명하지 못한 부분도 있을 수 있지만
  • 268. 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기 김찬웅 님 / 4월 25일 오후 4시 30분 〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3 이흥섭 님 / 4월 25일 오후 3시 20분 〈야생의 땅: 듀랑고〉 NoSQL 위에서 MMORPG 개발하기 최호영 님 / 4월 26일 오전 11시 듀랑고의 서버에 관련된 발표로
  • 269. 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기 김찬웅 님 / 4월 25일 오후 4시 30분 〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3 이흥섭 님 / 4월 25일 오후 3시 20분 〈야생의 땅: 듀랑고〉 NoSQL 위에서 MMORPG 개발하기 최호영 님 / 4월 26일 오전 11시 내일과 내일 모레에도 세션들이 준비되어있으니
  • 270. 만들고 붓고 부수고 - 〈야생의 땅: 듀랑고〉 서버 관리 배포 이야기 김찬웅 님 / 4월 25일 오후 4시 30분 〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3 이흥섭 님 / 4월 25일 오후 3시 20분 〈야생의 땅: 듀랑고〉 NoSQL 위에서 MMORPG 개발하기 최호영 님 / 4월 26일 오전 11시 관심있는 분들은 많은 참석바랍니다.
  • 271. WE'RE HIRING!http://what.studio/ 마지막으로 저희 왓 스튜디오는 다양한 직군에 대해서 채용을 진행하고 있으니
  • 273. WE'RE HIRING!http://what.studio/ 이상으로 발표를 마치겠습니다. 감사합니다.