게임 서버에서의 DB 사용 전략 - 1. DB를 사용하는 방식

Posted by 엘키의 주절 주절 on July 18, 2020

게임 서버에서 DB를 사용하는 것은 당연히 필요하다.

여러번 언급한대로 게임 서버에서는 정적 데이터만으로 서비스를 구성하는 것이 애초에 거의 불가능 하기 때문에 그렇다.

그렇다면 게임 서버에서 DB를 다루는 방법은 어떻게 나뉠까?

극단적으로 저장소로서만 사용

  • 게임 서버 메모리에 오랜 기간 캐싱하다, 특정 간격, 특정 이벤트 때만 기록
    • 특정 간격: 시간 단위. 5분, 15분, 30분, 1시간, 하루 등
    • 특정 이벤트: 로그아웃 시점, 특정 패킷 처리 전, 채널 변경, 존 이동 등
  • 패킷 처리 과정에서 이미 데이터 무결성을 지켜주게끔 멀티 스레드 구조를 구축해놓았기 때문에, 저장 시점에 일관되게 잘 기록만 해준다면 무결성도 지키면서 성능 극대화가 가능하다.
  • 다만 메모리 보유기간중에 서버 크래시나, 커넥션 유실/재접속시와 같은 상황에서 유실/복사 같은 크리티컬 이슈가 생기기 쉽다.

Stored Procedure(이하 SP)를 활용해 DB 의존형 로직 구성

  • 이 경우에 트랜잭션을 묶는 지점을 SP의 의존하므로, 자연스레 잠김과 병목 지점이 DB로 몰린다.
    • SP 처리 결과를 무시하고 진행할 경우 2차, 3차 감염의 여지가 있으므로 그렇게 할 수도 없기에 모든 처리가 SP로 집중되면서 자연스레 병목이 된다.
  • 또한 상황에 따라 중복 로직이 구성되는 경우가 많다.
  • 많은 양의 데이터를 자주 요청/응답에 사용해야 되는 장단도 있다.
  • DB의 처리 결과를 반영하므로, DB 처리의 성공/실패가 그대로 메모리에 반영되므로 오차가 적다.
    • 운영툴이나 디비 데이터 변경과 같은 처리도 매끄럽게 이어지게 하기 쉽다.

DB를 적극 사용하되 SP는 사용하지 않고, 트랜잭션 관리도 게임 서버가 하는 구조.

  • 게임 서버가 처리한 것은 DB에도 반영되므로 유실/복사에서 자유롭다.
  • 트랜잭션도 게임 서버 구조가 잘 지켜준다면, 영향을 덜 받을 수 있어 트랜잭션을 안 걸 수도 있게 됨.
    • 그럼에도 거래라거나, GM툴에서 발생된 액션이라거나, 다른 컨텐츠와 겹친 DB 접근 같은 상황을 막기 위해서 트랜잭션을 걸게 되는 경우가 많이 발생한다.
      • 이를 서버 구조적으로 소화하게끔 의도하는 것이 필요하다.
  • 보통 DB 저장 속도보다, 게임 서버 처리량이 많게 동작하므로 여전히 DB의 병목 가능성을 내재하게 됨.
    • 그 가능성은 SP를 사용하는 접근보다는 낮다

DB를 적극 사용하는 것처럼 의도하되, 캐시 서버를 두는 구조.

  • 게임의 캐시 서버는 Redis를 웹에서 사용하는 경우와 다르게, DB를 쓰는 것처럼 호환하고 무결성을 지키게 커스텀하게 구현되는 경우가 많다.
    • 내부적으로 Redis를 쓸 수도 있지만, 기본적으로 추상화 레이어와 규칙을 만들어 데이터 무결성을 지키는 호출을 보장하는 커스텀 캐시 서버를 둔다.
  • 성능적으로 극단적인 저장소 사용처럼 DB를 기다리지 않을 수 있다. (저장 시점 제외)
    • 캐시 서버가 DB의 처리량에 앞서 많은 부분을 커버해주고, 임시 처리 해주므로 성능에 덜 영향을 받는다.
  • 트랜잭션 관리를 캐시 서버가 대행하게 함으로써 복잡도를 낮춘다.
    • 겹칠 때만 체크해서 순서를 지켜주거나, blocking을 걸어서 지키게 할 수 있다.
  • 데이터를 캐시 서버에서 관리해주므로, 게임 서버 크래시로 인한 유실/복사 이슈에서도 유연해진다.
  • 레이어가 하나 더 해지는 만큼 관리 이슈나, 캐시 서버의 규칙, 관리 방법, 장애 대응이 추가로 필요해진다.

이 외에도 더 있을 것이다. 기본적인 접근은, DB를 저장소로만 사용하는가 로직 처리소로 사용하는가와 캐시 활용 여부 정도라고 볼 수 있다.

또한 캐시 서버나 미들 웨어의 역할에 따라 각 선택별 단점을 커버하는 기능을 중간에 끼워넣음으로써 해소하는 방법도 있다.

전반적으로 목적은 쓰루풋을 최대로 끌어올리면서 장애 요소를 제거하거나, 한가지 목적에 치우치거나 같은 선택과 집중이 엿보인다.

아무래도 DBMS는 서비스중엔 변경/확장이 쉽지 않고, 추가적인 DBMS 도입도 쉽지 않은 만큼 여러가지 측면에서 고민이 될 것이다.

이 글에서는 주로 RDB = DB라고 칭했는데, NoSQL을 메인 DB로 사용하는 접근과, 보조 DB로 사용하는 접근과 같이 나뉠 수도 있을 것이다.

현재 관점에서 접근의 연장선으로 케이스를 확장하는 관점에서 NoSQL 이야기와 함께 다음 글에서 이어가보도록 하겠다.