• 주제: MMORPG 랭킹 서버 만들기
  • 강연자 : 남지 - 컴투스 / TD(Technical Director)
  • 발표분야 : 서버, 개발
  • 강연시간 : 2021.11.19(금) 17:00 ~ 17:50
  • 강연 요약 : 랭킹 서버의 과거와 현재, 간단한 랭킹 만들어보기, MMORPG에서 랭킹 시스템 구축 팁



  • ■ 갤러그의 랭킹 - 40년 전에도 랭킹은 있었다


    컴투스 RAON 스튜디오의 남지 TD(Technical Director)는 월드 오브 제노니아라는 MMORPG를 제작하고 있다. 남지 TD는 앞선 두 개의 강연을 봤는데, 너무 재밌었다며, 자신이 준비한 강연은 프로그램 쪽이라 재미가 없을 거라는 농담으로 강연을 시작했다.

    "랭킹 서버라는 것은 사실 평범한 주제다. 그러나 이 주제를 왜 골랐느냐. 랭킹 서버를 만드는 법을 검색해보면 그나마 설명하는 게 딱 하나 나온다. 외국 사이트엔 좀 있지만, 그렇게 많지 않다. 없는 이유를 생각해보면 누구나 다 만들 수 있어서이기도 하겠지만, 그렇게 쉽지만은 않은 일이라서 그런 것 같다. 인디게임을 만드시는 분들과 이야기를 많이 했다. 게임을 정말 힘들게 만들었는데, 나중에 랭킹이라는 것을 붙여보고 싶을때 힘겨움을 느끼신다는 거였다."

    "현재 수많은 온라인게임이 있다. 웬만한 게임들은 다 랭킹이 있다. 굳이 만들지 않아도 상용 플랫폼에서 가져와 붙이면 된다. 생각해보면 90년대 말, 2000년대에는 랭킹이 필수 요소는 아니었던 거 같다. 그런데, 랭킹이라는것 자체가 더 옛날 오락실에서도 볼 수 있었던 거였다. 혼자 하다가 게임 오버되면 내 이름을 새기는 랭킹 시스템, 다 기억이 날 것이다."

    "그런 오락기를 생각해보면 오락기마다 랭킹을 저장하는 형태였을 것이다. 인터넷이 없었으니까. 오프라인에서 랭킹을 처리하는 개념도를 보면 이런 방식이다. 점수를 기록하고, 저장소에서 점수를 수집하고, 높은 점수별로 정렬하고, 화면에 나타내는 과정이다. 오프라인에서 랭킹을 처리하는 코드는 다음과 같다. 엄청나게 간단하다."








    ■ 랭킹을 만들땐? - 기록, 수집, 정렬, 보고




    "온라인에서의 랭킹 역시 같다. 웹 브라우저에서 기록하는 건 똑같다. 데이터베이스에 적고, 그 데이터베이스를 읽어와서, 정렬한 다음에 보여주는 게 과정이 일치한다. 코드 역시 간결하다. 다음은 조금 복잡한데 redis를 사용하는 방법이다. redis는 데이터를 저장하고 조회할 수 있는 범용 프로그램이다. redis에는 엄청난 기능들이 많이 추가되어있다. redis에는 랭킹에 사용할 수 있는 좋은 기능이 있다. 데이터를 넣자마자 자동으로 정렬되고 그냥 가져오기만 하면 된다."

    "랭킹을 만들 땐 딱 네 개만 기억하면 된다. 기록, 수집, 정렬, 보고. 이 네 가지가 다다. redis를 사용하지 않고 랭킹을 만들 때 몇 가지 팁을 드리겠다. 왜 강력한 툴인 redis를 사용하지 않느냐고 물어볼 수도 있겠다. 서버 프로그래머 입장에서, 서버 장애가 발생했을 때 난감할 수도 있다. redis는 우리가 만든 게 아니기 때문이다. 장애 발생 시 메뉴얼을 다 따라 해야 한다. 그래서 redis를 도입했을 때 얻는 편리함과 문제를 잘 저울질해서 선택해야 한다."

    "게임 서버에서도 랭킹을 처리할 수도 있다. 그러나 MMORPG에선 상황이 달라지는데, 서버 연산이 너무나 많아서 게임 서버와 랭킹 서버를 분리하는 경우가 많다. 예전에 스포츠 게임을 개발했었는데, 그때 데이터베이스 프로그래머들이 랭킹을 처리해준 적 있다. 나중에 얘기를 해봤는데 싫어하더라. 게임 서버는 입출력이 아주 많은데, 보편적으로 게임 서버에서 처리하길 꺼리는 경우가 많다."



    ■ 필터링과 캐싱 - 거르고, 저장하는 것




    "수집, 정렬 과정을 효율적으로 하려면 두 가지 방법이 필요하다. 필터링과 캐싱이다. 적당한 단어가 떠오르지 않아서 쓰던 단어들을 가져왔다. 필터링은 거르는 것이고, 캐싱은 저장하는 것이다. 모든 행위 결과를 수집하기에는 너무 많다. 랭킹 집계에 쓸만한 데이터만 가져와야 한다. 몇 레벨 이상, 마지막 접속일 며칠 이내인 캐릭터 데이터만 가져오면 효율적으로 랭킹을 매길 수 있다. 이게 필터링이다."

    "프로그래머분들은 다 공감하겠지만, 캐싱 자체가 redis다. 메모리에 상주하면서 서버와 통신하는 것이다. 랭킹을 처리하기 위하여 매번 데이터베이스에 질의를 하지 않고, 일정 주기로 데이터를 디비로부터 갱신하고, 메모리에 저장된 데이터를 기반으로 랭킹을 산출하는 것이다. 실시간 랭킹 개념이란 게 있지 않나. 내가 경험치를 조금만 더 먹으면 1등이 되는 경우라고 상상해보자. 경험치를 획득해서 랭킹을 확인해봤는데 아직 2등이다. 대부분 게임이 그럴 것이다. 바로 갱신되는 경우는 redis같은걸 사용해서 점수를 밀어 넣자마자 정렬이 되는 경우다. 그러나 동시 접속자 수가 만 명일 경우, 랭킹을 만 명이 동시에 조회하는 건 말이 안 된다. 대부분의 MMO게임들은 다 명시를 해놓는다, 언제 랭킹이 갱신이 된다. 마치 실시간인 척 하는 거다. 유저들도 큰 관심이 없다. 대다수의 유저들은 랭커가 아니니까. 랭커들은 좀 민감할 수도 있겠다. 그러나 현실적으로는 캐싱을 해서 일정 주기마다 랭킹을 갱신할 수밖에 없다."

    "캐릭터가 상위 몇 퍼센트에 포함되는지 필요한 때도 있다. 모든 집계 대상을 캐싱하여 랭킹을 일일이 매겨두면 가능한 일이긴 한데, 앞에서 말했듯이 필터링으로 해당 캐릭터가 캐싱에서 빠질 수도 있고, 매번 해당 캐릭터의 랭킹 정보를 주는 일은 과부하가 일어날 것이다. 그래서 현재 랭킹 데이터에서 점수와 순위의 선형적인 함수 관계를 추출하여 랭킹 데이터에 실어 보낸다면 점수만 가지고 대략 상위 몇 퍼센트인지 알 수 있을 것이다."