58
Live Operation by Adbrix Node.js와 MongoDB를 이용한 멀티-테넌트 인프라 구축사례 IGAWorks 백정상

(GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

Embed Size (px)

Citation preview

Page 1: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

Live Operation by AdbrixNode.js와 MongoDB를 이용한 멀티-테넌트 인프라 구축사례

IGAWorks백정상

Page 2: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

발표자

• 넥슨• 클래식 RPG (바람의나라 ~ 테일즈위버)

• 엔씨소프트• 스틸독, 마법천자문 온라인, MxM

• 블루윈드• 가로세로 for kakao, LINE QUIZ

• IGAWorks• Adbrix, Live Operation

Page 3: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

발표의 목적

Page 4: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

목적

• 다수 앱이 사용하는 운영툴을

• 짧은 시간 안에

• 혼자서 다

• 개발해야 할 때 겪은 경험(삽질)과

• 지혜를

• 편한 마음으로 공유

Page 5: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

내용

• 거창한 것은 없습니다

• 현실 타협만 가득합니다

• 꿀팁을 드리려 노력했습니다

Page 6: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

개발 동기

Page 7: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

앱을 출시 하기까지

• 앱 디자인

• 앱 컨텐츠 개발

• 수익화 모델 준비

• 운영 및 관리 툴

• 퍼블리싱 준비

• 런칭

Page 8: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

전체 개발 기간을 100으로 놓으면

1 10090

앱디자인및컨텐츠개발 그외작업

Page 9: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

개발사가중요하게생각하는것

컨텐츠 개발

Page 10: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

컨텐츠 개발이 거의 끝나면

Page 11: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

나머지작업들이지연되면

출시 일정 연기

Page 12: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

개발사가 진짜 원하는 것

Page 13: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

무엇을 도울 수 있을까

Page 14: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

무엇을 도울 수 있나

• 클라우드 서버를 제공?

• 네트워크 라이브러리?

• BaaS?

• 게임 컨텐츠 빌더?

• 결론• 컨텐츠 개발은 개발사가 직접 하는 게 맞겠다

• 라이브 운영이라면 도울 수 있겠다

Page 15: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

라이브 운영 서비스

• 지금 당장 중요한 고객들에게

• 푸시도 날리고

• 공지도 보여주고

• 리워드도 주고

• 쿠폰도 뿌리고

• 크로스 프로모션도 해주고

• 캠페인 결과를 리포트로 보여주는

• 앱 운영에 필요한 모든 기능을 제공하자

Page 16: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

프로젝트 요구사항

Page 17: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

요구사항

• 쉽게 사용 가능하도록 무료 서비스

• TCO 최소화

• 하나의 클라우드 인프라에 모든 앱이 서비스 가능하도록

• 하나의 인프라에 장애가 발생해도 서비스에 문제가 없어야 함

• 유저그룹 실시간 타게팅이 가능해야 함

• 실시간 결과 리포트가 되어야 함

• 365일 24시간 서비스

• 혼자서 만들면 얼마나 걸릴 것 같아?

Page 18: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

왜 우리에게 주어지는 시간은 늘 3개월인가

Page 19: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

테크 스택무엇을 가지고 만들까

Page 20: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

프론트-엔드 웹 서비스

• 웹 페이지 서비스는 대규모 인프라가 불필요

• 고민할 것 없이 ASP.net MVC + bootstrap + MSSQL

• 성능과 생산성을 동시에

Page 21: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

백-엔드 웹 서비스

• ASP.Net MVC VS node.js

• C#이냐 자바스크립트냐

• 윈도 라이선스냐 생산성이냐

• 빨리 만들어야 한다

• 대부분의 요청이 간단한 CRUD일 것이라 판단

• 손에 익고 오픈소스인 node.js 선택

Page 22: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

node.js

• 비동기 I/O 프레임웍

• google V8 + libuv

• 간단한 형태의 대량 비동기 I/O 리퀘스트 처리에 적합

• 활발한 에코 시스템

Page 23: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

데이터베이스 요구사항

• 시스템에서 저장하는 정보• 애드브릭스에서 얻는 유저 디바이스에 대한 정보 (1일마다 갱신)

• 개발사가 저장하는 정보• 유저 행동으로부터 실시간으로 얻는 정보 (실시간 갱신)

• 각 개발사마다 저장하는 정보의 형태가 다르다

• 하나의 일반적 스키마로 정의하기 어렵다

• 모든 컬럼이 검색 조건

Page 24: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

고려했던 기술

• mariaDB + Redis?• 앱별로 다른 스키마를 어떻게 일반화 할 것인가

• MongoDB• 2.6 기준으로 insert 퍼포먼스가 별로

• 스키마 없음

• node.js와 궁합이 좋음 (같은 자바스크립트 기반)

• 다양한 인덱싱

• Couchbase• 준수한 성능, 꽤 괜찮은 리플리케이션

• 아쉬운 인덱싱

Page 25: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

MongoDB

• BSON 도큐먼트 저장소

• 다양한 인덱싱 방법 지원

• 메모리-맵드 파일 기반

• 준수한 읽기 성능

• 스키마 없음

• Mongoose.js를 쓰면 node.js로 빠르게 구현 가능 하겠구나

Page 26: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

킥오프!

Page 27: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

개발 환경 정리

• 프론트-엔드 : ASP.net MVC + bootstrap

• 백-엔드 : Node.js 0.10.x

• 데이터베이스 : MongoDB 2.6.x

• ODM : Mongoose.js

• BDD : Mocha

• IDE : VS2012, Webstorm

• OS : Ubuntu 14.04 LTS

• SDK : iOS / Android

• Deployment : AWS (Tokyo)

Page 28: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

빠른 프로토타이핑

• 모든 백엔드 API 구현에 1주일정도 소요

• 웹 프론트엔드 작업 2주

• 프로토타입이 2주만에 나옴

• 만족스러운 생산성

Page 29: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

초기 시스템 구성

애드브릭스웹사이트

백엔드 API

몽고DB(단일인스턴스)

모바일디바이스(SDK 연동)

캠페인 API(푸시서비스)

액티비티트래킹

디바이스액티비티트래킹그룹

Page 30: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

고민

• DB 퍼포먼스 == 서비스 퍼포먼스

• 데이터베이스 리소스를 어떻게 앱마다 쪼개서 제공할까

• 안정성은 어떻게 유지해야 할까

• 성능 최적화는 어떻게?

• 모니터링은 무엇으로?

• 멀티-테넌트 인프라?

Page 31: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

멀티-테넌트 인프라

Page 32: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

멀티 테넌시의 4대 요소

• 안전한 분리• 사용자 데이터는 격리되어야 함

• 서비스 외부에서 타 앱 리소스에 접근 불가능

• 가용성• 리소스 하나에 문제가 생겨도 전체 서비스에 문제가 발생하지 않아야 함

• 서비스 보장• 일정 수준의 SLA 보장

• 관리• 전체 시스템 모니터링이 가능해야 함

Page 33: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

데이터 격리

• 제일 고민이 컸던 부분

• 구글링 해보니 굉장히 다양한 방법이 있었음

• 1 앱 == 1 EC2 인스턴스?

• 1 앱 == 1 docker container?

• 1 앱 == 1 database?

• 1 앱 == 1 collection?

Page 34: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

1앱 == 1 EC2 인스턴스

Page 35: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

1앱 == 1 docker container

• 장점• 확실한 형태의 분리

• 분리 대비 리소스 효율적

• 단점• 앱이 10000개가 된다면? 10000개의 이미지를 관리?

• dbpath로 데이터를 관리 하자니 관리 코스트가 크다

• 이미지가 커져서 서비스 중 이전해야 한다면?

• 결국 관리 시스템을 만들어야 하는 상황

Page 36: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

1앱 == 1 database

• 장점• 2.6 기준으로 데이터베이스별 쓰기락 지원으로 병렬성 확보

• 컬렉션 관리가 용이

• Mongoose 연동이 간편

• 단점• 기본 생성되는 데이터파일 사이즈가 64MB(데이터) + 16MB(네임스페이스)

• 앱 5000개면 도큐먼트가 0개여도 400GB

• 비효율적인 스토리지 사용

• Provisioned IOPS EBS는 매우 비쌈

Page 37: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

1 앱 == 1 collection

• 장점• 비용 효율적

• 단점• 2.6 기준 병렬성 이슈 발생

• 앱과 컬렉션간의 매핑이슈와 uniqueness문제

• 네임스페이스 이슈

• 1앱이 여러 컬렉션을 써야 한다면?

• Mongoose에서 지원하지 않음

Page 38: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

1앱 == 1 컬렉션을 선택

• 제일 비용 효율적

• 차기 버전에서 document-level locking이 지원될 것이란 소문• 3.0에서 wiredtiger가 도입되면서 그것이 실제로 일어났습니다!

• 애드브릭스 앱키 + 컬렉션 이름으로 uniqueness를 설정

• 컬렉션 이름을 해싱하여 저장하고 mapper를 구현

• CBT을 해보니 Write보다는 Read 위주인 사용 패턴

• 페이지 폴트만 조심하면 성능 하락 요인이 적다

Page 39: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

개념적으로

애드브릭스웹사이트

백엔드 API 몽고DBappKey:103932name:users

db.[‘103932_users’].find()

Page 40: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

리소스 접근 제어

• 공용 REST API 미지원

• 로그인 외 모든 리소스 요청에는 인증 세션을 요구

• 각 컬렉션에 접근권한 부여

• MongoDB를 격리된 VPC 내에 배치하고 WAS만 접근 가능하게 설정

Page 41: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

가용성

• WAS• 는 무조건 stateless

• ELB와 오토-스케일 그룹을 통해 구성

• DB• 리플리카 셋을 구성

• 제일 비용 효율적인 구성을 하자

• 2개의 리플리카 셋 멤버를 2대의 r3.2xlarge에

• 1개의 아비터

• 1TB의 provisioned IOPS EBS * 2

Page 42: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

서비스 보장

• AWS님만 믿고 가자

• 다행히 서비스동안 mongodb 리플리카 멤버 1번 사망한 것 빼고 리소스에 문제 생긴 적이 없음

• EBS의 경우 기본 데이터 3중화

• ELB에 등록할 경우 알아서 availability zone을 균등하게 분배

Page 43: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

관리

• 직접 (급하게) 만든 Control tower• Github -> docker image -> auto-scale group 자동화

• MongoDB Management Service 도입

• Amazon CloudWatch

Page 44: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

꿀팁 모음

Page 45: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

디비가 꽉차면 어쩌지?

• 130여개 앱이 사용하자 벌써 100GB+

• 디스크 용량 제한에 걸리면 어떡하지?

Page 46: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

샤딩

• 몽고디비 샤딩은 컬렉션 단위

• 오토 리밸런스 작동시 리소스 관리가 어려움

• 앱 추가될 때 마다 컬렉션 생성하고 수작업으로 샤딩 걸고..;;;

• 현실적으로 손이 많이 가서 제외

Page 47: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

수동 페더레이션

• 온라인 게임 서버 증설하는 방식

• 기존 리플리카 셋의 페더레이션 아이디는 0

• 새로운 페더레이션 멤버가 추가될 때 마다 페더레이션 아이디 증가

• 이후 등록되는 앱 정보는 다음 페더레이션 멤버에 추가하도록

• 페더레이션 멤버 추가시 수작업이 필요

• 페더레이션 맵퍼 수작업 구현

Page 48: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

최적화

• 크게 두 가지만 기억하세요

• Locking 이슈

• Indexing 이슈

Page 49: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

Lock 관리

• 일괄입력, 일괄 업데이트 금지• 모든 쓰기 행동은 비동기로 짧게 진행되도록 처리

• 일괄처리의 휴리스틱 최대치는 1000개

• MapReduce나 Aggregate 금지• 서비스에 영향을 미칠 정도의 과부하 발생

• 바보같은 스토리지 형태로 쓰세요

• 복잡한 계산은 스케일 아웃 가능한 WAS에서 하도록

• 가급적이면 read는 secondary preferred로

• CEP의 경우 Capped Collection을 쓰면 write성능 대폭 상승

Page 50: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

Index 관리

• 컬렉션당 최대 인덱스 개수는 64개

• 인덱스 대상의 최대 사이즈는 1KB

• 네임스페이스를 최대한 키울 것. 1GB 정도까지

• explain()의 생활화

• 인덱스 생성을 가급적 적게 하고• 한번에 많이 할 경우엔 foreground로

• 빈번하게 해야 할 경우엔 background로 설정

• 인덱스가 많으면 당연히 write 퍼포먼스 하락

• Projection을 통해 Covered Query를 최대한 활용하세요

Page 51: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

멀티-테넌트 컬렉션 관리자

• 스키마가 없어서 좋긴 한데

• 앱마다 저장되는 정보가 다르고

• 인덱스도 다 다르고

• 권한도 다르고

• 어떤 컬럼이 커스텀 유저 액티비티인지

• 어떤 컬럼이 시스템 필수인지 누군가는 알아야 함

• 결국 다 관리해주는 컬렉션 관리자를 구현해야 했습니다 orz

Page 52: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

Mongoose.js 관련

• 패스트 프로토타이핑땐 좋았음

• 멀티-테넌트 인프라에선 비추천

• 기본적으로 1개의 독립적인 디비를 사용하는 형태를 기준으로 개발됨

• Native driver로 구현하시는 것이 정신 건강에 좋습니다

Page 53: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

실시간 유저 타게팅

• 유저 그룹 조건을 저장해뒀다가

• 매번 필요할 때마다 쿼리

• MongoDB 검색은 진짜 빠름

• 메모리 사이즈가 클 수록 성능 배가

• 효율적인 인덱싱이 최대 과제

Page 54: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

맺음말

Page 55: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

현재 간략 구성도

애드브릭스웹사이트

백엔드 API

모바일디바이스(SDK 연동)

캠페인 API(푸시서비스)

액티비티트래킹

디바이스액티비티트래킹그룹

푸시센더그룹

푸시이벤트스토어

MongoDB RS Federation 0

페더레이션관리자

Page 56: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

사용량

• 130+ 업체에서 무료로 사용 중

• 16,000,000+ 일 최대 유저 커스텀 액티비티 트래킹

• 300,000,000+ 누적 푸시 메시지 발송

Page 57: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

후기

• 빠르게 시작해서 돌아가는 그림을 보고

• 비즈니스와 기술적 요구사항 존중하니

• 엄청나게 많은 부분을 수정하고 다시 만들었습니다

• 근데 딱 6개월 걸렸습니다

• 정확히 예상 일정의 2배 걸렸네요

• Node.js + MongoDB 조합 쓸만합니다

Page 58: (GameTech2015) Live Operation by Adbrix의 Node.js와 MongoDB를 이용한 멀티테넌트 인프라 구축사례

감사합니다