버클리db 를 이용한 게임 서버 제작

33
버버버 DB 버 버버버 버버 버버 버버 버버버 [email protected]

Upload: -

Post on 26-Jun-2015

3.611 views

Category:

Technology


8 download

DESCRIPTION

임베디드 DB 인 버클리DB 를 이용하여 게임서버를 만들어보았다.

TRANSCRIPT

Page 1: 버클리Db 를 이용한 게임 서버 제작

버클리 DB 를 이용한 게임 서버 제작

공봉식[email protected]

Page 2: 버클리Db 를 이용한 게임 서버 제작

버클리 DB 란 ?

오라클에서 만든 임베디드 DB 오픈소스 라이브러리

Page 3: 버클리Db 를 이용한 게임 서버 제작

특징

Page 4: 버클리Db 를 이용한 게임 서버 제작

라이브러리 형태의 DB 이다

별도로 존재하는 게 아니라 응용프로그램에 이식되어서 동작하는 임베디드 형태의 DB 이다 .

응용프로그램에 종속적이다 .

Page 5: 버클리Db 를 이용한 게임 서버 제작

단일 key/ 단일 data 구조

DB 가 하나의 key 와 하나의 data 로 구성되어 있다 .

key 와 data 모두 바이너리 형태

매우 심플한 구조

Page 6: 버클리Db 를 이용한 게임 서버 제작

SQL 문을 지원하지 않는다

관계형 DB 가 아니기 때문에 SQL 문을 지원하지 않는다 . Get, Put, Erase 같은 단순한 API 로 데이터에 접근한다 .

* Join 지원하지 않는다 .

Page 7: 버클리Db 를 이용한 게임 서버 제작

뛰어난 성능

임베디드되고 , SQL 문을 지원하지 않기 때문에 성능이 뛰어나다 .또한 멀티코어를 지원하여 scalability 가 뛰어나다 .

Page 8: 버클리Db 를 이용한 게임 서버 제작

ACID 를 보장하는 트랜잭션

ACID 를 보장하는 트랜잭션 기능을 지원한다 .데드락 디텍션 기능을 제공한다 .RMW 기능을 제공하여 데드락을 회피한다 .

Page 9: 버클리Db 를 이용한 게임 서버 제작

파일 / 메모리 양쪽 모두 사용 가능

파일 DB 로 쓸 수 있고 순수한 메모리 DB 형태로도 사용 가능하다 .파일 DB 를 쓸 경우 트랜잭션 로그를 통해 복원 기능을 제공한다 .메모리 DB 로 사용하면 FILE I/O 로 인한 오버헤드를 없앨 수 있다 .

Page 10: 버클리Db 를 이용한 게임 서버 제작

사용이 간단하다

env.BeginTxn(&txn);db.Get(&txn, &key, &data, flag);db.Put(&txn, &key, &data, flag);db.Erase(&txn, &key, flag);txn.Commit();

이런 형태로 매우 간단한 API 를 제공한다 .

Page 11: 버클리Db 를 이용한 게임 서버 제작

다양한 언어를 지원한다

버클리 DB 는 C 언어로 제작되었으나C, C++, JAVA, Python, C#, Ruby 등 다양한 언어를 지원하고 있다 .또한 모바일 기기 부터 대용량 서버까지 활용 범위가 넓다 .

Page 12: 버클리Db 를 이용한 게임 서버 제작

오픈소스 라이센싱

오픈소스 프로젝트는 무료로 사용할 수 있으나 그렇지 않을 경우에는 별도로 구입해야 한다 .

Page 13: 버클리Db 를 이용한 게임 서버 제작

단점

Page 14: 버클리Db 를 이용한 게임 서버 제작

외부에서 데이터를 볼 수 없다

데이터가 바이너리 형태로 들어가 있어서 별도의 툴을 통하지 않고는 외부에서 볼 수 없다 .

최신 버전에서는 SQLite 를 지원하여 SQL 문과 도구를 지원하고 있기는 하다 .

Page 15: 버클리Db 를 이용한 게임 서버 제작

백업 , 미러링 등의 고급 기능이 없다 .

상용 관계형 DB 에서 제공하는 고급 기능이 많이 빠져있다 .꼭 필요한 기능만 제공하는 편 .

Page 16: 버클리Db 를 이용한 게임 서버 제작

통계용으로 사용하기 힘들다

SQL 문을 지원하지 않기 때문에 실행 계획도 세우지 않고 , 인덱스도 Key 하나만 제공한다 .

따라서 통계용으로 사용하기는 힘들다 .통계용 관계형 DB 를 따로 둬야 한다 .

Page 17: 버클리Db 를 이용한 게임 서버 제작

게임 서버와 버클리 DB

Page 18: 버클리Db 를 이용한 게임 서버 제작

시작은 다크스타 .

다크스타는 Sun 에서 추진했던 JAVA 로 만든 오픈소스 게임서버 엔진이다 .Sun 이 오라클에 인수된 뒤 현재는 공식적인 지원이 끊기고 RedDwarf 란 이름으로 명맥이 유지되고 있는 상태 .

다크스타는 버클리 DB 를 이용하여 게임서버를 제작했다 .

Page 19: 버클리Db 를 이용한 게임 서버 제작

서버의 태스크 분할 형태로 변화

공짜 점심이 끝나고 서버의 코어수가 늘어나면서 멀티 코어를 최대한 활용하기 위해서 태스크 분할 형태로 서버가 변화하고 있다 .

태스크 분할 형태로 갈 경우 가장 큰 문제는 데이터 락킹이다 .

Page 20: 버클리Db 를 이용한 게임 서버 제작

HitTask(){

BeginTransaction();

A = GetForRead();B = GetForUpdate();

B.Hp -= A.Att;

Commit();}

* 태스크의 예 트랜잭션을 시작한다 .

A 에 대해 읽기 락을 건다 .이제 A 에 대해서 쓰기락을 걸 수 없다 .

B 에 대해 쓰기 락을 건다 .이제 B 에 대해서 읽기 /쓰기 락을 걸 수 없다 .

실제 B 데이터를 수정한다 .

트랜잭션을 커밋한다 .B 의 변경점을 적용하고 A 와 B 의 락킹을 푼다 .

Page 21: 버클리Db 를 이용한 게임 서버 제작

하지만 이런 시스템을 구축하는 건 쉽지 않다 .

STM 구축하는 건 쉽지 않고 , 안정성과 성능을 모두 잡기가 힘들다 .특히 , 데드락과 레이스 컨디션 같은 문제를 잡기가 힘들다 .

Page 22: 버클리Db 를 이용한 게임 서버 제작

버클리 DB 는 이 모든 요구조건을 충족한다 .

상용 소프트웨어에서는 별도로 구입해야 한다는 조건을 제외하면 STM 구축에 있어서 가장 빠르고 좋은 해결책이라고 생각된다 .

Page 23: 버클리Db 를 이용한 게임 서버 제작

데모 서버엔진

Page 24: 버클리Db 를 이용한 게임 서버 제작

목적 : 버클리 DB 를 이용하여 태스크 분할 서버엔진을 구현해 본다 .

제작 기간 : 2010 년 4 월 5 일 ~ 2010 년 4 월 12 일 (7 일 )(1 일 평균 5 시간 작업 )

구현 언어 : C++

사용 라이브러리 : BerkeleyDB, TBB, google.test, STL 등

Page 25: 버클리Db 를 이용한 게임 서버 제작

데이터를 관리한다 .내부에는 버클리 DB 를 사용하고 있다 .트랜잭션 , 데이터 체크아웃 , 체크인 기능을 제공한다 .

응용프로그램 동작을 정의한다 .단순한 광부 AI 를 제작하여 동작하도록 구현하였다 . (*Programming game AI by example 2 장 )

네트워크를 담당한다 .데모버전에서는 실제 네트워크를 구현하지 않고 mock 객체로 구현하였다 .

TBB 를 사용하여 태스크 스케쥴러를 작성하였다 .딜레이 태스크 , 반복 태스크등을 지원한다 .

Page 26: 버클리Db 를 이용한 게임 서버 제작

네트워크패킷

태스크 매니져

BeginTransacton

세션 핸들러 OnRecv()

Commit

1. 클라이언트로부터 메시지를 수신

2. 태스크 매니져에 메시지 처리 태스크를 추가한다 .

3. 태스크 시작에 트랜잭션을 시작한다 .

4. 실제 메시지를 처리한다 .이 과정에서 객체 상태가 변화한다 .

5. 태스크 마지막에커밋하여 변경점을 적용한다 .

Page 27: 버클리Db 를 이용한 게임 서버 제작

사용예

Page 28: 버클리Db 를 이용한 게임 서버 제작

// 광부를 만든다 .ServerMiner miner;m_minerRef = g_DataManager::Instance().CreateReference(&miner);

광부 객체를 DataManager 를 통해서 메모리 DB 에 쓰고 그 참조객체를 반환한다 .앞으로 생성한 광부를 객체를 접근하기 위해서 참조객체를 사용하게 된다 .

Task() {

ServerMiner* pMiner = m_minerRef.GetForUpdate();if (pMiner != NULL){

pMiner->receivedMessage(_msg);}

}

광부를 쓰기 권한을 읽는다 .

메시지를 처리함으로써 광부 상태가 변경된다 .

태스크 종료시 변경점이 자동으로 Commit 된다 .또한 데드락 발생시 RollBack 된 뒤 태스크가 일정 횟수까지 재실행 된다 .

Page 29: 버클리Db 를 이용한 게임 서버 제작

특징

Page 30: 버클리Db 를 이용한 게임 서버 제작

Application 에서는 싱글쓰레드Application 에서는 마치 싱글 쓰레드 처럼 프로그래밍 할 수 있다 .실제로는 멀티 쓰레드로 돌고 있지만 태스크 양단을 트랜잭션으로 보호하기 때문에 쓰기 객체에 접근하는 쓰레드는 하나이다 .

Page 31: 버클리Db 를 이용한 게임 서버 제작

멤버 변수로 포인터를 사용할 수 없다 .

데이터매니져에 저장되는 객체의 멤버 변수로 포인터를 사용할 수 없다 .멀티쓰레드 상황이기 때문에 포인터가 삭제되었을 수있고 쓰레드세이프 하지 않기 때문이다 .

대신 가져오고자 하는 객체에 대한 참조객체를 멤버 변수를 가지는 것은 가능하다 .

Page 32: 버클리Db 를 이용한 게임 서버 제작

최소 의존 컴포넌트 구현

멀티 코어를 최대한 활용하기 위해서 각 객체의 사이즈를 최소로 하고 의존관계를 최소화 할 필요가 있다 .

각 객체는 단일 목적 / 단일 객체 라는 원칙으로 최소 의존 컴포넌트를 구성한다 .

Page 33: 버클리Db 를 이용한 게임 서버 제작

반복자나 무거운 작업은 별도 태스크로 분리

많은 객체를 순환하거나 시간이 오래 걸리는 작업은 여러 태스크로 분리하는게 좋다 .

많은 객체를 순환할 필요가 있을 경우 분할 병렬 처리하고 , 외부 DB 작업 등 시간이 오래 걸리는 작업은 요청과 응답 처리를 별도 태스크로 분리하여 동작하도록 하는게 좋다 .