[▲ 문대경 아이펀팩토리 대표]
인벤에서는 게임업계 1.5세대 인물로 안정적인 게임서버엔진인 아이펀 엔진을 개발한 아이펀팩토리의 문대경 대표님을 모시고 서버 관련 컬럼을 기고 받게 되었습니다.

문대경 대표는 1999년 넥슨 입사 후 2005년까지 넥슨에서 출시되는 다수의 프로젝트 서버 프로그램을 책임졌으며, 현재 아이펀팩토리의 대표로 게임서버 엔진인 '아이펀엔진'을 개발하였습니다.

아이펀팩토리가 개발한 '아이펀 엔진'은 네트워크, DB처리, 분산 시스템 등 게임 서버 구현에 필요한 필수 기능을 손쉽게 구현해 개발 시간 단축을 돕는 모바일 게임 서버엔진입니다.

그 네 번째 시간으로 P2P vs. 클라이언트-서버 모델 Part 1이란 타이틀을 가지고 설명하도록 하겠습니다.

* 본 내용은 본지의 편집방향과 일치하지 않을 수도 있습니다.



P2P vs. 클라이언트-서버 모델 Part 1

첫 회에서 게임 서비스를 구성할 때 사용하는 네트워크 모델들에 대해서 간단하게 언급했었는데, 이 중에서 클라이언트-서버 모델과 P2P 모델에 대해 두 회에 걸쳐 좀 더 깊이 살펴보도록 하자. 이번 회에서는 클라이언트-서버 모델에 대해 설명을 하고 다음 회에 이어서 P2P 모델에 대해서 설명을 하도록 하겠다.

클라이언트-서버 모델: 중앙 집중 방식

집집마다 ADSL 인터넷이 설치된 것은 채 20년도 되지 않는다. 그전에 인터넷이라는 것은 학교 전산실에서나 경험해 볼 수 있었고, 컴퓨터 전공자들에게만 익숙한 것이었다. 지금은 컴퓨터를 사도 메인보드에 랜 포트가 달려나오고, 노트북 컴퓨터 같은 경우는 유선 랜 포트가 거추장스럽다고 아예 WiFi만 지원할 정도로 네트워크 연결 측면에서 많은 진보를 이루었지만, 당시에 랜카드는 당연히 별도로 사서 설치하는 것이었고, 그나마도 OS에서 이를 인식시키는 것은 나름 까다로운 작업이었다. 조금 더 쉽게 설명하면, 컴퓨터에 랜 카드를 설치해주는 것만으로도 컴퓨터 잘하는 동네 오빠로서 이성에게 호감을 얻을 수 있는 정도? (물론 나에게는 그런 여자 후배는 없었다… 왜냐면…. 나는 공대니까…)

▲ 예전에는 랜카드를 별도로 설치해야했다. 크고 아름다운 랜카드의 위용 (출처: https://en.wikipedia.org/wiki/Network_interface_controller)

이런 초고속 인터넷 (영어로는 broadband Internet) 의 대중화 과정은 비단 우리나라에서만 그런 것이 아니었고, 그 때문에 일반적으로 서버라는 존재는 압도적인 계산 능력을 갖춘, 특별히 관리되는 존재로 인식되었다. 우리가 일반 컴퓨터에서 사용하는 인텔 x86 CPU가 서버에도 활용되기 시작한 것 역시 역사가 그다지 오래되지 않았다.

이런 배경 때문에 대부분의 인터넷 서비스는 가장 직관적이고 일반적인 형태로, 정보를 몰아넣고 중앙에서 관리하는 강력한 컴퓨터가 빈약한 사용자 컴퓨터에 서비스를 제공해주는 형태로 갖춰지게 되었다. 정보를 제공(서빙)해주는 사람이라는 뜻에서 ‘서버'라고 불리게 되었고, 정보를 활용하는 고객이라는 의미에서 ‘클라이언트'라고 불리게 되었다. 그러니 클라이언트-서버 모델은 컴퓨터 네트워크 초창기부터 가장 일반적으로 활용되어온 서비스 구성 방식이다.

그런데 클라이언트와 서버라는 단어는 어떤 물리적인 구분이 아닌 역할에 따른 구분이라고 생각하는 것이 바람직하다. 태생부터 서버, 클라이언트 구분이 있는 것이 아니라 그 순간 무슨 일을 하느냐에 따라 구분이 되는 거라고 이해하면 되겠다. 즉, 아무리 서버라도 또 다른 서버의 서비스를 활용한다면 서버도 그 순간에는 클라이언트 역할을 하는 것이다. 예를 들어 게임 서버는 DB 서버에 정보를 요청하는데 이 순간에 DB 서버로서 게임 서버는 클라이언트가 되는 것이다. 또 내 스마트폰도 대부분은 클라이언트로 동작하지만, WiFi Hot Spot 을 열어주는 것과 같은 행동을 하면 “인터넷 연결”이라는 서비스를 제공하는 서버 역할을 하게 되는 것이다.

클라이언트-서버 모델은 서비스의 구성이 직관적이고, 서비스를 변경하기 위해서는 거의 서버만 바꾸면 된다는 매력적인 장점이 있다. 우리가 인벤 사이트에 새 기사를 보기 위해서 인벤 관리자가 기사를 올리는 것이 아니라 클라이언트(웹 브라우저) 수정 작업을 해야 한다면 얼마나 불편할지 생각해보라. 그 때문에 서비스 (콘텐츠) 관리 측면에서 클라이언트-서버 모델은 유리한 점이 많다.

그러나 거의 모든 중앙집중 방식이 갖는 취약점 역시 그대로 갖고 있어서, 클라이언트-서버 모델은 서버 쪽 과부하라는 골치 아픈 문제를 안고 있다. 과부하는 서버 기계에도 나타날 수 있고, 서버 기계가 물려 있는 네트워크에도 나타날 수 있다. 그리고 클라이언트-서버 모델은 이런 문제를 하드웨어 업그레이드나 증설로 해결한다. 즉, 더 좋은 기계로 바꾸거나 더 많은 기계를 붙이고, 더욱 대역폭이 큰 회선을 붙이게 된다. 그리고 경우에 따라 인터넷 통신사에 구분 없이 빠른 접속 속도를 보장하기 위해서 인터넷 회선을 통신사별로 연결해 놓기도 한다. 그리고 당연하겠지만, 이런 서버/네트워크 관리는 서비스 제공자로서는 높은 비용 지출을 의미한다. 나는 전체 매출의 30% 이상을 서버/네트워크 비용으로 내는 경우도 보았다. 그러니까 클라이언트-서버 모델은 서비스 (콘텐츠) 관리의 편의성을 위해서 부하의 집중화와 높은 물리 장비 관리 비용이라는 단점을 지게 되는 것이다.

Scale-out 방식과 scale-up 방식

서버 대수를 추가해서 서비스를 확장하는 것을 엇비슷한 애들이 옆으로 계속 늘어나는 것처럼 보인다고 해서 수평 확장성, 혹은 scale-out 이라고 부른다. 그리고 더 좋은 기계로 바꿔서 서비스를 확장하는 것을 scale-up 이라고 부른다. 2GHz짜리 CPU 와 4GHz CPU가 가격 차이가 두 배가 아니듯이 더 고사양의 하드웨어의 (그러니까 scale-up 인 경우) 가격은 천정부지로 올라간다. 마치 자동차에서 제로백이 낮은 수퍼카들 세계에서는 제로백 1초 줄이기 위해 엄청난 돈을 써야 하는 것과 같은 이치다. 어쩌면 게이머들 그래픽 카드를 예로 드는 것이 이해가 더 쉬울 수도 있겠다. 그 때문에 성능이 떨어지더라도 서버를 붙이는 대로 서비스가 확장되는 scale-out 이 고사양의 기계로 바꿔야 하는 scale-up 보다 가성비가 훨씬 높고 더 선호된다.

그런데 문제는 이렇게 서버 대수를 늘리는 방식이 모든 서비스에서 가능한 것은 아니라는 점이다. 대부분의 웹 사이트들은 서버 대수를 늘리면 쉽게 확장할 수 있지만 직접 프로그램을 만드는 경우는 확장성을 보장되게 만드는 것은 지극히 어려운 일이다.

웹 서비스가 쉽게 확장 가능한 이유는 서비스의 핵심 부품인 “웹 서버” 프로그램이 확장성이라는 좋은 특성이 있기 때문이다. 그리고 싱글 플레이 위주의 모바일 게임들 역시 내부적으로는 웹 서버 혹은 그와 유사한 방식을 사용하기 때문에 서버 대수를 늘리는 방식으로 손쉽게 확장할 수 있다.

하지만, 웹 서버 프로그램은 이런 확장성을 공짜로 얻는 것이 아니라 디비 서버에 부하를 떠넘기는 대신 얻는다. 그 때문에 웹 사이트처럼 비교적 정적인 서비스를 제공하는 경우는 큰 문제가 없을 수 있지만, 실시간 멀티플레이 게임 서버처럼 굉장히 동적인 서비스는 웹 서버를 활용하게 되면 극악의 서버 당 동접수가 나오게 된다.

그 때문에 PC 온라인 게임이든, 모바일 게임이든 실시간 콘텐츠가 있는 게임은 직접 서버 프로그램을 구현해왔고, 보통 소켓(Socket)이라는 네트워크 프로그래밍용 라이브러리로 직접 만든 서버라는 뜻으로 “소켓 서버" 라고 부른다. 그런데 소켓 서버 자체는 클라로부터의 네트워크 연결과 패킷 전송만 담당할 뿐, 서로 다른 서버에 접속한 클라끼리의 통신이나, 클라의 서버 간 이동 등의 것들은 별도로 분산 처리라 구현이 필요해진다. 그러니 서버 프로그래머가 소켓 서버를 만들더라도 이렇게 분산 처리할 수 있게끔 만들지 않으면 게임 서버는 확장 가능하지 않다.

그런데 이런 분산 처리는 컴퓨터 공학에서도 별도의 영역으로 존재할 정도로 꽤 깊이 있는 영역이고, 그렇다 보니 상당히 높은 능력과 노력, 시간까지 필요하다. 그 때문에 서버 프로그래머는 단위 서버 당 동접도 높여야 하고, 서버를 붙여서 서비스가 확장 가능하게도 만들어야 하는 어려움을 겪게 된다.

그런데 그걸 구현할 프로그래머가 없다고 출시해야 할 게임 서비스를 못 내보내게 되는 것도 곤란한 만큼, 게임 개발사들은 복잡한 분산처리를 우회하여 기획적으로 포장하는 방법을 생각해냈다. 바로 채널이라는 개념의 도입이었다.

채널: 수평 확장 구조 대신, 채널별 고사양 서버 할당을 통한 확장성 확보 방식

게임에 접속해서 채널을 선택하는 방식의 게임이라면, 서버 군들을 분산 처리 구현을 통해 하나로 묶은 게 아니라, 아주 높은 확률로 채널 별로 서버, 혹은 몇 개의 서버들을 할당한 게임일 수 있다. 채널끼리는 서로 공유되는 내용이 없고 심지어 디비도 분리되어 있어서 아이디 중복 체크도 채널 별로 이루어진다면 거의 확실히 이런 방식이다. 그리고 채널이라는 용어 대신 “서버"라고 직설적으로 말하기도 하고 아니면 “월드" 같은 기획적으로 포장된 다른 용어를 쓰기도 한다. 채팅 프로그램 중에서도 이렇게 채널을 구분한 경우가 많다.

▲ 서버 선택 화면 (이미지 출처: http://ohharu.com/583)


이런 채널 방식은 서비스를 하나로 유지하면서 키우는 대신, 작은 서비스 여러 개로 쪼개 놓은 형태이다. 그리고 작은 서비스로 쪼개도 충분히 모객이 가능해서 개개의 작은 서비스가 살아남을 수 있다면 나쁘지 않은 방식이라 볼 수 있다.

내가 지금보다 머리에 털이 많고, 어려운 것을 구현해내서 스스로 능력을 증명하는데 열을 올리던 20대 시절에, 나는 이런 채널 방식을 좋아하지 않았다. 그리고 넥슨 시절 내 상사 역시 이런 방식은 분산 처리 기술이 없는 경우나 하는 것이라고 굳게 믿고 있었다.

바람의 나라와 리니지를 통한 레슨: 사업/운영적 관점 역시 서비스 구성에 큰 영향을 미친다.

당시에 넥슨은 바람의 나라를 주력 게임으로 하고 있었고 선릉역 인근 사무실 2층 한쪽 방에 조립 데스크톱을 잔뜩 집어넣고 유저가 늘어날 때마다 서버를 확장해 나갔었다. 어떤 유저들은 “역시 돈슨. 그렇게 돈을 안 썼냐?”라고 생각할지도 모르겠다. 나 역시 처음에는 이게 조금 부끄러웠다. “우리도 돈 좀 들여서 브랜드 서버 좀 쓰고 싶다" 라는 생각도 했었다. (그 후 넥슨이 최초로 도입한 브랜드 서버는 후지쯔 서버였다.) 그리고 조립 서버를 쓰는 통에 나는 160대 정도 서버를 조립하고 OS 를 깔아야만 했고 이 역시 상당히 힘든 작업이라서 완제품 서버를 쓰고 싶었다.

그러나 나중에 깨달은 거였지만, 이는 엔지니어 관점에서 높은 가성비를 갖는 방법이었고 그만큼 확장성에 자신이 있었기 때문에 선택하는 방법이었다. 그리고 나는 몇 년 뒤에 구글 역시 유사한 방식으로 서버를 운영한다는 것을 알았다. 넥슨은 케이스를 일부 개조했지만, 구글은 아예 케이스를 벗겨 놓고 썼다는 점이 다르지만… (솔직히 구글도 그렇게 쓴다고 하니까 넥슨에서의 경험이 더 자랑스럽게 느껴진 것도 있다. 이놈의 망할 사대주의 -_-)

▲ 구글의 서버. 최고의 가성비를 위해서 이런 조립 PC 를 사용했고, 발열을 줄이면서 한 랙에 더 많은 서버를 집어 넣기 위해서 케이스까지 제거했다. (출처: http://www.cnet.com/news/google-uncloaks-once-secret-server-10209580/)

사실 그 당시 넥슨이 이런 방식에 은근 자부심을 품고 있던 것은 다분히 경쟁사인 엔씨소프트를 의식했기 때문이다. 엔씨는 넥슨보다 좋은 사양의 기계를 쓰고 있었다. 그리고 엔씨는 신규 서버를 추가하는 방식으로 서비스를 확대해 나갔다. 거기에 대해 넥슨은 “신규 유저나 바람의 나라 처음 만들어질 때 유저나 하나의 월드에서 다 같이 플레이할 수 있고, 10만 명이 넘는 유저가 같은 월드에서 플레이할 수 있다" 라는 서버에 대한 자부심, 서부심을 밀고 있었다.

그런데 이게 꼭 좋은 것이 아니었다. 시장에서는 바람의 나라보다 리니지가 더 큰 성공을 올렸기 때문이다. 돈만 잘 벌면 장땡이라는 말이 아니라, 우리는 운영 관점에서 놓치고 있는 것들이 있었다. 먼저 유저들은 그렇게 사람이 바글바글한 서버를 좋아하지 않았다. 아이디나 닉네임도 선점하고 싶고 게임 안에서 탑랭커도 되고 싶은 게 인지상정인데, 바람의 나라는 나보다 5년 전에 플레이한 유저보다 고랩이 되기 쉽지 않았기 때문이다. (더구나 그때는 아이템 판매 없이 월 정액제 요금뿐이었으니 오로지 경험치 노X다 외에는 상위 랭커로 올라갈 수 없었다.) 최근에 세븐 나이츠 신규 서버 관련된 광고를 본 사람들이라면 쉽게 이해할 수 있을 텐데, 신규 서버는 그만큼 유저들에게는 기회의 땅인 것이다.

▲ 모든 사람이 같은 출발선에서 시작할 수 있다는 점 때문에 신규 서버는 유저들에게 좋은 기회가 된다. (출처: 세븐나이츠)

이 때문에 넥슨에서도 바람의 나라를 결국 서버 별로 구분하기 시작했다. 기존의 서버는 연 서버라는 이름으로 하고 무휼 서버라는 이름의 서버가 추가되었다.

그리고 게임 운영자들도 낮은 관리 부담 때문에 채널별 서버 관리를 선호하는 경우도 있다는 것을 알게 되었다. 1만 명짜리 서버 10개로 하는 것이 10만 명짜리 서버 하나 보다 서버가 죽었을 때 충격이 덜할테니까…. 그러니 지금 생각해보면 엔씨가 수평 확장성을 구현을 못 한 게 아니라 오히려 안 한 게 아닐까 하는 생각도 든다. 엔씨가 하려고 하면 당연히 했을 것이다. (여러분은 지금 거대 두 기업 사이에서 밉보이면 안 되는 소상공인의 정치적 중립 노력을 보고 계십니다.)

물론 채널 별로 서비스를 쪼개는 방식은 채널별로 독자적으로 운영 가능할 정도의 사용자 수가 확보된다는 가정이 필요하다. 만일 RPG 게임의 채널을 열었는데 유저가 100명 있다면 아마 그 안에서 유저들은 무인도에 혼자 떨어져서 혼자 플레이한다는 느낌 때문에 별로 즐겁지 않을 것이다. 그렇다고 중복되는 유저 아이디도 있는 마당에 채널을 합치기도 곤란한 상황이 발생할 수도 있다. 따라서 서비스의 구성에 항상 옳은 답이 있다기보다는 상황에 가장 잘 맞는 방법을 택할 수 있는 유연함이야말로 좀 더 높은 경지가 아닐까 싶다.

정리하면, 클라이언트-서버 모델은 대부분의 인터넷 서비스에 적용되는 일반적인 방식이며, 많은 게임 서비스 역시 이런 방식으로 구성된다. 그런데 클라이언트-서버 모델은 중앙 집중식이기 때문에 서비스 콘텐츠 관리는 수월할지 모르지만, 서버와 네트워크가 물리적인 병목이 되고 이를 해결하기 위해서 큰 비용이 들어간다. 그리고 병목을 해결하는 방식으로 비슷한 사양의 기계를 계속 추가해나가는 scale-out 방식도 있고, 더 좋은 기계로 바꾸는 scale-up 방식도 있다. 두 방법 중에 가성비 측면에서 일반적으로 scale-out 방식이 선호되지만, 구현에 들어가는 노력을 고려할 때 단일 서버에 많은 유저를 붙여야 하는 기획이 아니라면 채널로 구분하고 채널별 서버를 scale-up 해서 높은 사양의 서버를 쓰는 방식도 널리 사용된다. 이때 채널 방식은 채널 별로 충분한 사용자 수가 확보되지 못하면 폭망하게 된다.

원래는 이번 화에 P2P까지 다루려고 했으나 분량 조절에 실패하여, 다음 화에서는 클라이언트-서버 방식에 대비되는 목적으로 등장한 P2P 방식에 대해 설명하고 P2P 구현에서 어렵게 생각되는 것들, 그리고 P2P 가 적용 가능한 서비스 환경에 대해서 설명을 하도록 하겠다.