왜 게임 서버를 직접 만들 수 밖에 없는가?
소규모 게임에는 일부 적용
MMO용으로도 일부 시도
- 실패하였음
- 느리고 쓰기 불편
왜 실패했을까?
MMO 게임의 특징
엄청 많은 사람이 함께 게임을 한다.
Massive 문제의 해법들
멀티스레드
백엔드 분산
서버 샤딩
플레이어 제한등
정리
게임 서버의 핵심구조는 게임 디자인(기획)에 매우 민감하게 반응한다.
역으로 서버의 구조로 인해 디자인에 제한이 생긴다.
서버 프레임워크 전체를 가져와 쓰는 것은 게임의 유니크함을 해칠 수 있다.
기초 설계
스레드 모델 확장
single thread
입력을 폴링으로 처리한다
모든 로직이 순차적으로 처리된다
구조가 간단하다
lock 문제가 발생하지 않는다
멀티코어의 이점을 사용할 수 없다
스레드 잠김이 없는 경우 꽤 빠르다
input thread
입력이 비동기 IO일 때 사용 가능하다
로직이 IO 스레드에서 실행된다
별도의 스레드를 생성하지 않는다
Lock 문제가 발생한다
스레드를 관리하지 않는다
스레드가 잠기는 경우에 성능 손해가 비교적 적다
custom thread pool
로직이 스레드 풀에서 실행된다.
실행 모듈에 작업 큐가 있다.
스레드 수를 조절해, 성능을 최적화 할 수 있다
입력 순서와 처리 순서가 달라질 수 있다
Lock 문제가 발생한다
스레드가 잠기는 경우에는 성능 손해가 크다
- DB나 외부 서비스 동기화 쿼리에 의한 성능 손해가 매우 크다
object bound thread
앞의 모델에서 입력 순서 문제를 해결
스레드 별로 리소스 관리자가 할당된다
특정 객체를 타겟으로 하는 입력간의 순서가 보장된다
Lock 문제가 거의 발생하지 않는다
전체 객체 검색이 불가능하다
객체가 많이 몰리게 되는 곳이 있다면 성능 손해가 매우 크다
설계 확장 하기
MMO의 가장 큰 특징 = 플레이어간의 교류(Interaction)
인터랙션은 지리적인 관계로 이루어지는 경우가 많다
기본적인 동작
CreateObject : 객체가 시야 안에 들어왔다(시야 안에 들어왔다)
DostroyObject : 객체가 파괴되었다(시야밖으로 나갔다)
Broadcast : 객체가 액션/이동되었다(상태/외형이 변경되었다)
FindInRange : 거리안에 있는 객체 검색
GetDistanceWith : 다른 객체와의 거리 참조
시야범위 안에 있는 객체들의 목록 검색과
시야 범위에 따른 객체들의 입장 / 퇴장 이벤트 => 공간 분할을 이용해서 검색 속도를 향상
다양한 공간 분할 방법
동적 분할
쿼드 트리: 공간을 재귀적인 호출로 4개의 자식 노드로 분할하는 방법
서클 트리
정적 분할
타일: 구현이 간단하고 초기화 비용이 거의 없다. 시야 거리를 동적으로 바꾸기 어렵고 객체의 수에 속도가 변화가 없다.
서버가 보는 심리스 월드
세계가 단절 없이 이어져 있다.
같은 공간분할 데이터로 관리된다.
눈에 보이는 객체는 같은 서버에 배치하는 것이 좋다.
같은 메모리 공간상에 없으면 처리가 매우 복잡하기 때문이다.
거대한 심리스 월드 해결 방법
걸어서 이동할 수 없는 곳은 모두 분리한다.
프록시 객체를 이용해서 여러 서버에서 분산가능 (안정화 시키기 어렵다)
메모리, CPU를 늘린다 (공간 분할 후 부분적으로 독점해서 멀티스레드로 확장)
출처: 임태현 / 넥슨코리아
http://ndcreplay.nexon.com/NDC2013/sessions/NDC2013_0040.html
'NDC > Server' 카테고리의 다른 글
[NDC 2015] 피파온라인3 서버 구조와 85만 동접 포스트 모템 (0) | 2023.01.05 |
---|---|
[NDC 2014] WCF를 이용하여 쉽게 만드는 모바일 게임서버 (0) | 2022.10.21 |
[NDC 2014] 분산서버 구축의 ABC (0) | 2022.10.19 |
[NDC 2014] Rx와 Functional Reactive Programming으로 고성능 서버 어플리케이션 만들기 (0) | 2021.12.02 |
[NDC2014] WCF를 이용하여 쉽게 만드는 모바일 게임서버 (0) | 2021.12.02 |