Project DarkStar 는 왜 실패했을까?

SUN의 Java 기반의 게임 서버 프레임웍인 Project DarkStar 는 왜 실패했을까? 내가 예전에 생각했던 것과, 요즘 들어 든 생각들을 모아서 요약해봤다.

1. 게임 서버는 게임 제작 기간의 임계 경로(critical path)가 아니다

게임 서버는 대부분의 경우 “게임 제작 시작”과 동시에 작성되기 시작하는 경우는 거의 없다. 그래서 엔진을 사서 얻을 수 있는 이익 중 하나인 “시간 단축”으로 인한 효과가 적거나 없다. 물론 상대적으로 안정화된 코드 베이스를 빨리 얻을 수 있다는 이점은 존재 한다.

2. 게임 서버 구조에 대한 컨센서스가 없다.

게임 클라이언트는 각 모듈들 – 게임 로직, 렌더링, AI, … – 이 어느 정도 잘 분해되어 있다 – 적어도 그런 종류의 고민이 많이 끝난 상태다. 하지만 서버의 경우 게임 로직과 게임 서버 자체의 구동을 위한 아랫 단의 구분이 성능 저하없이 잘 이루어져 있는 경우가 드물다. 그래서 이런 서버용 게임 엔진은 시장에 나와 있는 예가 거의 없다. 내가 아는 범위 내에서는 DarkStar 프로젝트와, BigWorld Technology의 BigWorld Server 정도 밖에 없다. 그리고 이 범위 내에서, 상업적으로 충분한 성공을 거둔 게임(eg: 연간 1m USD 이상의 매출)은 없다.

그리고 각 프로젝트마다 실제 서버 구조 차이는 꽤나 컸다 – 내가 본 사용 서버 코드만 4개가 넘는데, 각자 다른 구조를 차용하고 있고, 기본적인 도구 수준에서나 같은 모습을 볼 수 있다. 하지만 DarkStar 는 일단 단일 구조로 나왔고, 커스터마이징이 가능하긴하지만 전체 구현 자체는 MMORPG 를 노린 것으로 보인다. 그렇기에 충분히 큰 시장을 가지지 못했다고 생각된다.

3. Java 사용의 문제

* Java GC가 신뢰할 정도로 빠른가? 분명히 Java는 서버 어플리케이션의 throughput 면에서는 만족할 만한 성능을 내고 있고, 이런 분야 – 각종 트랜잭션 기반 금융 업무, 웹 페이지 렌더링 … – 에서는 거대한 시장을 이끌고 있다.

하지만 반응 속도 면에서, 최소한 일정 수준 이상의 반응 속도가 필수적인 게임 서버에서도 이게 보장되는가? ((물론 클라이언트에서 이런 반응 속도를 속이기 위한 각종 테크닉을 사용한다. 사용자의 입력에 대한 일단의 액션을 보여주고, 최종적인 결과 처리는 서버의 판단 후에 반영된다거나(이럼 RTT 만큼의 시간은 걸린다). ))  게임 서버에 가장 많은 부하가 걸릴 시간 – 메모리가 가장 모자라서 GC가 강제화라도 되어야할 시점 – 에 GC가 “한꺼번에” 일어나면 반응성의 문제가 생길 수 밖에 없다.

이건 약간 샛길로 새는 얘긴데, GC 문제는 C#에서도 역시 나타날 수 있다. 최근 런칭한 마비노기 영웅전 서버가 어느 정도 예측가능한 주기(<1일)로 비정기 점검(…을 가장한 서버 셧다운 넘기기)하는게 GC문제가 아닐까 의심 중이다. GC로 메모리가 모자라면 아주 일정한 수순을 거쳐서 서버가 죽게 된다.

1. GC로 반응(지연) 시간 증가

2. 큐에 작업이 쌓임

3. 더욱더 메모리가 필요해져서 GC 가 필요해짐

4. 악순환 시작. 실제 작업 로드를 내리는데 CPU가 사용되는게 아니라 GC에 들어감

5. 서버 사망

* 예전에 Rica 가 언급했던 서버/클라이언트 코드 공유 문제. 코드 생성기로 “우회”할 수는 있지만, 서버/클라이언트 코드 공유로 시스템 전체에서 중복을 제거하는 것도 무시못할 부분인데, 이 부분에서는 Java로 게임 클라이언트를 짜는게 거의 불가능한 상황 ((Java 용 게임 클라이언트 라이브러리의 수는 C++용 게임 클라이언트 라이브러리 수와 order-of-magnitude 의 차이가 난다. 질 적인 면에서는 그 성숙도에서 엄청난 차이가 날 게 틀림이 없음에야…)) 을 생각하면 좀 암울하다.

* Java 나 C# 류의 언어는 확실히 생산성이 높다. http://www.codinghorror.com/blog/archives/000299.html 참고. 하지만 여기서 말하는 “Write his own” 항들을 게임 서버에서는 적어도 현재로는 필요하기에 사실상 다 하고 있다. 혹은 게임 서버/서버 용 라이브러리가 있거나..

4. Java 가 새 하드웨어 기술을 잘 따라잡고는 있는가?

적어도 게임 쪽에서는 아니라고 생각한다. 게임 서버는 그렇게 “현재의 기술”만 가지고 만들어지질 않는다. 한 예로 DarkStar 가 타겟으로 잡았던 MMO 시장의 한 게임을 들어보자. EVE Online 이라는 게임이 있는데, 이 게임의 서버 구조는 어느 정도 알려져 있다 (참조: EVE Online’s Server Model)

이 게임은 서버 군(혹은 shard 란 명칭으로 흔히 부르는 그것)이라는 개념이 없다. 모든 사용자는 “하나의 논리적인 서버”에 들어가는 형태다. 이걸 가능하게 한 기술은 InfiniBand 라고 부르는 네트웍 기술덕인데, CPU 버스 수준의 통신 속도+지연 시간을 보장하는 네트웍 장치다(다만 point-to-point). 이런 상대적으로 low-level 한 기술을 나오는 즉시 사용하기에는 Java 언어 자체의 변경 속도가 느리다. 그렇다고 이걸 C/C++ 로 만든 드라이버를 작성하고, 이걸 DarkStar 같은 녀석 밑단에 JNI 연결하기엔 배보다 배꼽이 커질 것 같다. 게다가 이쯤 되면 프로그래밍 모델이 우리가 흔히 보는 UMA가 아니라 NUMA 모델에 가까워진다. 그것도 non-cc NUMA… Java는 아직 NUMA 에서 GC 구현조차 실험적 상태(experimental) 이다.

또다른 예로, 32bit –> 64 bit 넘어가던 시절에 만들어진 모 게임이 있다. 이 게임의 경우 64bit 운영체제가 시장에 나올 즈음을 타겟팅해서 작성되었는데, 출시가 늦어지면서(…), .dll 의 메모리 모델이 좀 다른 점을 이용해서, 공유 메모리 비슷한 형태로(…) 32bit 응용 프로그램이 쓸 수 있는 물리 메모리보다 더 많은 물리 메모리를 쓸 수 있게 수정해서 출시했다고 한다. ((이건 PAE 같은 CPU 확장 기능을 이용하면 32 bit OS 라도 16GiB~32GiB 수준의 메모리를 쓸 수 있어서 가능한 것)) 이런 low-level 한 시스템 프로그래밍을 DarkStar 같은데 연동하는건 절대로 쉬운 일이 아닐 거다.

물론 Java 가 새 기술을 따라잡으면, Java codebase 전체가 쉽게 이동한다는 장점은 있다. 그렇지만 Java 의 현재 가장 큰 시장은 게임 서버가 아니기에, 이 쪽으로의 이동이 빠를리는 없다 – 적어도 현재 시점에선 그렇게 보인다.

5. 이식성 문제나 하드웨어 호환성 문제는 서버 프로그래밍에서는 큰 이슈가 아니다

타겟 하드웨어와 타겟 OS를 정해놓고 작업할 수 있기에, Java 의 장점이라는 이식성/호환성 문제는 아예 이슈거리가 되질 않는다. 오히려 타겟 하드웨어에 맞는 최적화를 “손 쉽게” 쓸 수 없는 Java 의 문제가 생긴다.

6. DarkStar 는 모든걸 만들어야 했다

DarkStar 의 실패 원인 중 하나는, DarkStar 의 “기능”으로 소개한 것 중 중요한 것들은 3rd party library로 있는 애들이 많다는 거다. 혹은, 시장이 될만한 MMOG 제작사들이 이미 인-하우스 툴이 갖춰졌을 시점이라는 것.

DISCLAIMER: 이 글은 rein 의 개인적인 견해이며, 소속 기관 어디와의 연관성도 없음을 밝혀둔다. 또한 이 글의 각 사실 관계에 관해서는 현재 알고 있는 바에만 기초했으며, 이걸 사용해서 얻어지는 직/간접적인 결과에 대해서는 rein은 아무런 책임이 없음을 밝힌다.

Jinuk Kim
Jinuk Kim

SW Engineer / gamer / bookworm / atheist / feminist

Articles: 935

16 Comments

  1. 마영전 서버는 긴급점검의 정기점검화가 진행되고 있는 듯 (…)
    분산처리로 현실타협 안 하고 어떻게 한 대에 꾸겨넣으려고 하는 것 때문에
    문제가 꽤 생길 수 있겠다는 걱정이 드네요.
    (덕분에 안 생기는 문제도 있겠지만…)

    • 분산 처리한다고 논리적으로 단일 서버가 아닌 건 아니겠지.

      그리고 “겨우 마영전 정도의 부하”로 한 대에 꾸겨넣었다고 죽는건 말이 안돼. 30K 300K 씩 붙고 버티는 논리 단일 서버도 있는 판국에…

      구조를 잘못 짰거나, 계산을 잘못했거나(구조가 버틸 수 있는 유저 수에 대해)겠지.

  2. Java 서버에서 응답에 지장을 줄 정도로 GC가 발생하는 경우는 Full GC 때입니다. Full GC 가 발생할 만큼의 부하가 걸리는 서비스 라면 처음부터 로드밸런싱에 신경을 써서 L4 와 서버들을 준비하게 됩니다. 선의 게임 서버 개발취소는 결국에 투입할 자원대비 벌어들일 수 있는 수입이 별로라는게 가장 크겠죠.

    • 게임 서버는 애초에 설계에 따라서 로드 밸런싱 자체가 의미없어지는 경우가 많습니다.
      로드 밸런싱이 쉬우려면 각 서버 단위가 “동등”하다는 가정이 있어야하는데, 게임 서버에선 그런 경우는 없지요(딱히 채널링이나 샤드 같은건 아예 직접적으로 보이게 구현을 하니).

      그리고 부하 자체가 서비스에 따라가는게 아니라, 게임 자체의 기획의도에 의존적인 경우가 더 흔합니다. 그래서 순간적으로 / 서버의 한 부분에 / 거대한 부하(초당 1000~4000 수준의 작업단위)가 단일 서버에 걸리는 일도 안 이상하게 일어납니다. 이렇게 부하가 걸리는 순간에 light weight GC 말고 다른 GC가 돌면 서버는 작업큐 꽉차서 뻗는거죠.

      SUN 입장에서(혹은 오라클 입장에서?) 자원 대비 수입은 별로일 거라고 생각한다는 점에는 동의합니다. 선의 게임 서버를 적어도 현재는 “아무도 쓰려고 하지 않는 것”으로 보이기 때문입니다. 결국엔 완성된 물건이 나오지도 못했으니까요(적어도 작년 GDC까지는 완성된 물건이 아니었던 걸로 보입니다)

  3. 저는 이전 프로젝트까지는 C, C++ 로만 서버를 개발하다가 결국 C#, Java 를 하지 않으면 안되는 상황으로 변해서 결국 이 2가지를 새로 배우면서 개발하고 있답니다.

    몇달전에 끝낸 프로젝트에서는 위 4가지 언어를 모두 사용해서 했는데 생산성과 성능, 안정성에서 모두 만족합니다. MSXML이나 SOAP toolkit 을 사용했다면 베이스 모듈개발만 1개월 소요될것을 2주만에 하고도 버그가 없는데 무척 만족했었죠. 물론 C#의 제어 불가능한 GC 때문에 스트링 객체를 제외한 모든 오브젝트들은 일이이 Dispose 하거나 Close 를 해야만 했었죠 C# 을 사용하는 의미가 좀 퇴색(?) 했지만 으외로 괜찮았습니다.
    (제가 언어에 잘알아서 이렇게 한게 전혀 아닙니다. SI 는 고객사가 준비한 하드나 요구사항에 따라서 이런식으로 해야하는 경우가 제법 많답니다.)

    사족으로 rein 님 블로그는 몇년 전부터 거의 매일 들어와서 보는데 부러울때가 참 많습니다. 저희쪽 업계는 native 언어로 내공이 쌓인 신입들이 거의 없습니다. 대부분 게임업계 쪽으로 갑니다. 10년 가까이 일했더니 오래된 경력친구들은 서서히 IT 업계를 떠나거나 관리자로 남아있고..
    블로그를 통해서 같은 팀원들끼리 개발관련 여러가지 생각을 주고받고 하면서 일하는게 참 부럽습니다. 앞으로도 좋은 글 많이 부탁드립니다.

    • 아하 게임 서버에 한정된 얘기가 아니었군요(밑 댓글 얘기).

      근데 저희도 GC 되는 언어로는 아직 서버 개발을 본격적으로 해본게 아니라서 생산성에 대해서는 그냥 여기저기 프로젝트들을 참고만 합니다(…).
      그리고 생산성 문제는 서버 일부를 C++이 아닌 언어로 하려고 이런 저런 시도(만?) 하고 있습니다.

      네이티브 언어를 잘하는 신입은 어느 업계나 부족한거 같아요. 이쪽도 그렇게 네이티브 언어 잘하는 신입이 흔한건 아니거든요.
      그렇게 좋은 글을 쓰는건 아닌데(..) 잘 보고 있으시다니 앞으로도 잘 부탁드립ㄴ다 ~_~

  4. Java로 서버를 개발하고 있는 저로서는 아주 좋은 내용이었다고 생각합니다. Java로 64 bit 어플을 개발하는 것은 실패(?)한듯 보입니다(제 생각에는). 성능도 그닥 좋아지지 않았지만, 메모리 문제.. 32bit에 비해 2배가 커지는 문제가 발생을 하죠.. ^^;;그리고, 하드웨어에 특화된 서비스가 없기때문에 울며 겨자먹기로 JNI를 이용해야 되지만, Sun에서도 JNI의 안정성을 이유로 권고하지 않고 있는거 같습니다.
    그래도 게임서버(주로 IOCP를 사용하는듯)가 아닌 서버에서는 Java 서버도 좋은 강점을 가지고 있긴 한것 같습니다. Multicore도 잘 활용(nio나 concurrent package) 하면, 대충 짠 C 서버보다 성능이 좋은 거 같네요.. ^^

    • 게임 서버처럼 응집도가 높은 서버만 아니면 mcsong 님 말씀대로, Java는 굉장히 좋은 선택이라고 생각합니다.
      특히 널리 알려진(그리고 표준화된) 인터페이스들도 많고, 어느 정도 응집도가 있어도 concurrent package 같은 류의 구성은 참 좋거든요. (C++의 경우 boost 나 ACE 등을 쓸 수는 있지만, 이건 사람들이 싫어하는 경우가 너무 많아서 -_-)

Leave a Reply