벤치마크 #

이 평가에서 당사는 일반적으로 대규모 멀티플레이어 게임을 구축하기 위해 사용하는 몇 가지 핵심 API를 테스트하는 여러 워크로드에서 Nakama를 벤치마킹했습니다.

이 워크로드는 Nakama의 최신 하드웨어 친화적이고 확장 가능한 아키텍처의 성능 이점을 보여주기 위해 다양한 하드웨어 구성 세트에서 실행되었습니다.

결과에서 알 수 있듯이 Nakama의 성능은 하드웨어 규모가 커질 수록 좋아집니다. 단순화된 클러스터 관리에서 일반적으로 더 나은 하드웨어 및 규모의 경제에 대한 액세스에 이르기까지 규모의 확장 및 확대에 따라 다양한 이점이 있습니다.

방법 #

벤치마크는 강력한 분산 부하 테스트 도구인 Tsung을 사용하여 수행되었습니다.

Tsung 워크로드는 단일 데이터베이스 인스턴스를 사용하여 몇 가지 다른 구성으로 단일 노드 배포(Nakama OSS) 및 클러스터 모드(Nakama Enterprise)에서 Nakama를 벤치마크합니다.

데이터베이스 인스턴스 하드웨어는 I/O에 병목 현상이 발생하지 않도록 모든 구성 및 워크로드에서 일정하게 유지되었습니다. 일부 데이터베이스 바운드 API도 테스트했지만 이러한 벤치마크는 Nakama의 기능에 중점을 둡니다.

Tsung 서버는 Google Compute Engine(GCE)에서 실행됩니다. Nakama OSS 및 Enterprise는 모두 Heroic Cloud 인프라에서 실행되었습니다.

실제 워크로드 전에 워밍업 실행이 실시되지 않았습니다.

설정 #

Tsung / 데이터베이스 #

Tsung 토폴로지는 마스터 노드 1개와 20개의 슬레이브 노드로 구성됩니다. “이 설정은 모든 벤치마크 실행에서 그대로 사용되었으며 하드웨어 사양은 다음과 같습니다:

Tsung 메인Tsung 중복데이터베이스
인스턴스 유형n1-standard-32n1-standard-32전용 코어 vCPU
vCPU / Mem6 / 8GB3 / 2GB8 / 30GB
IOPS (읽기/쓰기)--3000

데이터베이스는 Google CloudSQL에 설정되었습니다.

Nakama #

다음 세 가지 구성에 대해 벤치마크 워크로드를 실행했습니다:

Nakama OSS

  • 1 노드 - 1 CPU / 3GB RAM

Nakama Enterprise

  • 2 노드 - 1 CPU / 3GB RAM (노드 당)
  • 2 노드 - 2 CPU / 6GB RAM (노드 당)

모든 컨테이너는 GCP 인스턴스 유형 “n1-standard-32"에서 실행되었으며 Heroic Cloud 플랫폼에 생성되었습니다. Nakama 노드는 GCP L7 부하 분산 장치 뒤에 있습니다.

워크로드 #

제안된 워크로드는 간편한 생산 준비 규모를 위해 Nakama의 처리량과 용량을 표시하기 위해 사용됩니다.

다음 워크로드에 대한 벤치마킹 결과를 제시합니다:

  1. 동시 소켓 연결 수(CCU 수).
  2. 새 사용자 등록 처리량.
  3. 사용자 인증 처리량.
  4. Lua 런타임에서 사용자 지정 RPC 호출 처리량.
  5. Go 런타임에서 사용자 지정 RPC 호출 처리량.
  6. 사용자 지정 대결 핸들러를 사용한 권한 보유 실시간 대결 수.

다음 하위 섹션에서는 앞에서 설명한 작업 부하를 자세히 설명하며, 고려된 각 하드웨어 및 토폴로지 구성에 대해 Tsung이 수집한 벤치마크 결과에 대해서도 설명합니다.

결과 #

워크로드 1 - 동시 소켓 연결 수(CCU 수) #

이 워크로드는 사용자 인증, Nakama에 대한 소켓 연결 열기, 약 200초 동안 열린 상태로 유지하는 것으로 구성됩니다.

1 노드 - 1 CPU / 3GB RAM

연결된 사용자 수

벤치마크 등록
벤치마크 등록

2 노드 - 1 CPU / 3GB RAM (노드 당)

연결된 사용자 수

벤치마크 등록
벤치마크 등록

2 노드 - 2 CPU / 6GB RAM (노드 당)

연결된 사용자 수

벤치마크 등록
벤치마크 등록

Time to connect
HardwareMax Connectedhighest 10sec meanlowest 10sec meanHighest RateMean RateMean
1 Node - 1 CPU / 3GB RAM1954242.40 msec26.54 msec1340 / sec196.12 / sec34.21 msec
2 Nodes - 1 CPU / 3GB RAM (each)2755816.93 msec15.92 msec930 / sec161.52 / sec16.60 msec
2 Nodes - 2 CPU / 6GB RAM (each)3209220.17 msec18.18 msec1097.7 / sec187.82 / sec19.15 msec

위에 표시된 것처럼 단일 CPU 코어가 있는 단일 Nakama 인스턴스에는 최대 19,500명의 연결된 사용자가 있을 수 있습니다. 각각 2개의 CPU 코어로 최대 2개의 노드로 증가되는 이 값은 최대 32,000CCU까지 확장됩니다.

워크로드 2 - 새 사용자 등록 #

이 워크로드는 새 계정을 데이터베이스에 저장하는 게임 서버의 장치 인증 API를 통해 새 사용자 등록을 에뮬레이트합니다.

1 노드 - 1 CPU / 3GB RAM

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

2 노드 - 1 CPU / 3GB RAM (노드 당)

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

2 노드 - 2 CPU / 6GB RAM (노드 당)

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

Request statistics
Hardwarehighest 10sec meanlowest 10sec meanHighest RateMean RateMean
1 Node - 1 CPU / 3GB RAM29.07 msec20.10 msec849.6 / sec519.46 / sec24.60 msec
2 Nodes - 1 CPU / 3GB RAM (each)31.65 msec20.01 msec1014.3 / sec672.18 / sec25.95 msec
2 Nodes - 2 CPU / 6GB RAM (each)0.14 sec20.01 msec1160.8 / sec750.76 / sec28.46 msec

위에 표시된 것처럼 단일 Nakama 서버는 새 사용자에 대한 데이터베이스 쓰기 작업으로 24.60ms(평균)로 제공된 요청으로 최대 500 요청/초의 평균 부하를 처리할 수 있습니다. 이 속도로 게임은 매시간 186만 명의 새로운 플레이어를 생성할 수 있습니다. 이 값이 노드 2개로 확장되면 시간당 최대 270만 플레이어 계정으로 증가합니다.

워크로드 3 - 사용자 인증 #

이 워크로드는 게임 서버의 장치 인증 API를 사용하여 기존 사용자를 인증하는 것으로 구성됩니다.

1 노드 - 1 CPU / 3GB RAM

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

2 노드 - 1 CPU / 3GB RAM (노드 당)

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

2 노드 - 2 CPU / 6GB RAM (노드 당)

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

Request statistics
Hardwarehighest 10sec meanlowest 10sec meanHighest RateMean RateMean
1 Node - 1 CPU / 3GB RAM33.40 msec17.27 msec802.2 / sec499.63 / sec24.61 msec
2 Nodes - 1 CPU / 3GB RAM (each)27.87 msec16.81 msec1035.5 / sec673.42 / sec22.19 msec
2 Nodes - 2 CPU / 6GB RAM (each)76.85 msec16.95 msec1162 / sec776.77 / sec25.03 msec

워크로드 4 - 사용자 지정 Lua RPC 호출 #

이 워크로드는 Lua 런타임을 통해 노출되는 간단한 RPC 함수를 실행합니다. 이 함수는 페이로드를 JSON 문자열로 수신하고 디코딩한 다음 발신자에게 다시 에코합니다.

1 노드 - 1 CPU / 3GB RAM

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

2 노드 - 1 CPU / 3GB RAM (노드 당)

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

2 노드 - 2 CPU / 6GB RAM (노드 당)

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

Request statistics
Hardwarehighest 10sec meanlowest 10sec meanHighest RateMean RateMean
1 Node - 1 CPU / 3GB RAM26.18 msec15.01 msec976.5 / sec633.42 / sec20.22 msec
2 Nodes - 1 CPU / 3GB RAM (each)19.25 msec15.68 msec1192 / sec706.71 / sec17.48 msec
2 Nodes - 2 CPU / 6GB RAM (each)20.27 msec16.11 msec1383.4 / sec823.55 / sec18.16 msec

워크로드 5 - 사용자 지정 Go RPC 호출 #

이 워크로드는 Go 런타임을 통해 노출되는 간단한 RPC 함수를 실행합니다. 이 함수는 페이로드를 JSON 문자열로 수신하고 디코딩한 다음 발신자에게 다시 에코합니다.

1 노드 - 1 CPU / 3GB RAM

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

2 노드 - 1 CPU / 3GB RAM (노드 당)

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

2 노드 - 2 CPU / 6GB RAM (노드 당)

처리량 (요청/초)

벤치마크 등록
벤치마크 등록

Request statistics
Hardwarehighest 10sec meanlowest 10sec meanHighest RateMean RateMean
1 Node - 1 CPU / 3GB RAM26.12 msec14.42 msec975.9 / sec635.36 / sec19.97 msec
2 Nodes - 1 CPU / 3GB RAM (each)20.87 msec14.91 msec1205.7 / sec707.12 / sec17.29 msec
2 Nodes - 2 CPU / 6GB RAM (each)20.19 msec15.59 msec1386.4 / sec820.41 / sec18.00 msec

위에 표시된 것처럼 단일 Nakama 서버는 19.97msec(평균)로 제공되는 평균 최대 600 요청/초를 처리할 수 있습니다. 워크로드 5의 결과와 비교할 때 Lua와 Go 런타임 간의 결과가 매우 유사함을 알 수 있습니다. 이는 벤치마킹된 워크로드가 CPU 계산을 거의 일으키지 않기 때문이며 따라서 Lua 가상 머신의 차이에도 불구하고 결과가 비슷해집니다. CPU 집약적 코드를 사용하면 Lua 런타임의 RAM 사용량과 마찬가지로 성능 결과가 달라지기 시작합니다.

워크로드 6 - 사용자 지정 권한 보유 대결 논리 #

이 워크로드는 Nakama의 서버 권한 보유 멀티플레이어 엔진에서 실행되는 실시간 멀티플레이어 게임을 에뮬레이트합니다. 클라이언트와 사용자 지정 로직은 실제 멀티플레이어 게임이 아니지만 이 코드는 서버와 연결된 게임 클라이언트 간에 교환되는 메시지 측면에서 실제 사용 사례 시나리오의 근사치를 생성합니다. 이 워크로드에서 서버 및 클라이언트 로직에 대해 간략하게 설명합니다.

서버 측 로직 #

서버는 초당 10틱의 틱 속도로 멀티플레이어 대결을 실행합니다. 각 대결에는 최대 10명의 플레이어가 있을 수 있습니다.

서버는 클라이언트가 진행 중인 대결(플레이어 10명 미만)의 ID를 얻기 위해 쿼리할 수 있는 RPC 호출을 구현합니다. 이 API가 호출되면 서버는 대결 목록 기능을 사용하여 자리가 있는 대결을 찾고 첫 번째 결과를 반환합니다. 대결을 찾지 못한 경우 새 대결이 시작됩니다.

대결 루프 로직은 간단합니다. 서버는 클라이언트로부터 두 작업 코드 중 하나를 수신할 것으로 예상하고 다음 작업 중 하나를 수행합니다.

  1. 수신된 메시지를 클라이언트로 에코백합니다.
  2. 모든 대결 참가자에게 메시지를 브로드캐스트합니다.

클라이언트 측 로직 #

클라이언트 로직도 간단합니다. 각 게임 클라이언트는 다음 단계를 순서대로 수행합니다:

  1. 토큰을 받기 위해 Nakama로 기존 사용자를 인증합니다.
  2. 서버 RPC 함수를 실행하여 진행 중인 대결(자리가 있는)의 ID를 수신합니다.
  3. 실시간 API와 웹 소켓 연결을 설정합니다.
  4. 2단계에서 받은 아이디로 이 대결에 가입합니다.
  5. 180초 동안 클라이언트는 루프를 돌고 0.5초마다 작업 코드 1 또는 2가 포함된 메시지 전송을 번갈아 가며 수행합니다.

클라이언트가 보낸 메시지에는 각각 작업 코드 1 및 2에 대해 44자 및 35자의 문자열이 있는 고정 크기의 페이로드가 포함됩니다.

1 노드 - 1 CPU / 3GB RAM

연결된 사용자 수

벤치마크 등록
벤치마크 등록

2 노드 - 1 CPU / 3GB RAM (노드 당)

연결된 사용자 수

벤치마크 등록
벤치마크 등록

2 노드 - 2 CPU / 6GB RAM (노드 당)

연결된 사용자 수

벤치마크 등록
벤치마크 등록

이 결과는 이 워크로드가 관련되어 있기 때문에 클라이언트가 수행한 각 요청에 대한 평균입니다:

  1. 인증
  2. RPC 호출
  3. 웹 소켓 연결 및
  4. 웹 소켓 연결 통해 메시지 전송

결과에는 각 클라이언트 세션 내에서 수행되는 전체 요청 로직 집합이 고려됩니다.

Request statistics
Hardwarehighest 10sec meanlowest 10sec meanHighest RateMean RateMean
1 Node - 1 CPU / 3GB RAM42.21 msec1.07 msec126.5 / sec36.72 / sec15.06 msec
2 Nodes - 1 CPU / 3GB RAM (each)0.10 sec1.14 msec213.8 / sec54.68 / sec28.21 msec
2 Nodes - 2 CPU / 6GB RAM (each)41.82 msec1.07 msec350 / sec85.82 / sec15.93 msec

아래 표는 대결 중 교환되는 데이터 메시지와 함께 게임 서버가 처리하는 네트워크 처리량입니다. 클라이언트가 수신한 바이트 수가 전송된 바이트 수보다 훨씬 많다는 것을 알 수 있습니다. 클라이언트가 보낸 메시지의 50%는 위에서 언급한 대로 서버에서 모든 대결 참가자에게 브로드캐스트를 시작합니다.

Network Throughput
HardwareSent/ReceivedHighest RateTotal
1 Node - 1 CPU / 3GB RAMSent4.65 Mbits/sec157.92 MB
Received24.88 Mbits/sec809.65 MB
2 Node - 1 CPU / 3GB RAM (each)Sent5.90 Mbits/sec201.35 MB
Received31.96 Mbits/sec1020.68 MB
2 Node - 2 CPU / 6GB RAM (each)Sent7.64 Mbits/sec261.61 MB
Received40.54 Mbits/sec1.30 GB