벤치마크 #
이 평가에서 당사는 일반적으로 대규모 멀티플레이어 게임을 구축하기 위해 사용하는 몇 가지 핵심 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-32 | n1-standard-32 | 전용 코어 vCPU |
vCPU / Mem | 6 / 8GB | 3 / 2GB | 8 / 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의 처리량과 용량을 표시하기 위해 사용됩니다.
다음 워크로드에 대한 벤치마킹 결과를 제시합니다:
- 동시 소켓 연결 수(CCU 수).
- 새 사용자 등록 처리량.
- 사용자 인증 처리량.
- Lua 런타임에서 사용자 지정 RPC 호출 처리량.
- Go 런타임에서 사용자 지정 RPC 호출 처리량.
- 사용자 지정 대결 핸들러를 사용한 권한 보유 실시간 대결 수.
다음 하위 섹션에서는 앞에서 설명한 작업 부하를 자세히 설명하며, 고려된 각 하드웨어 및 토폴로지 구성에 대해 Tsung이 수집한 벤치마크 결과에 대해서도 설명합니다.
결과 #
워크로드 1 - 동시 소켓 연결 수(CCU 수) #
이 워크로드는 사용자 인증, Nakama에 대한 소켓 연결 열기, 약 200초 동안 열린 상태로 유지하는 것으로 구성됩니다.
1 노드 - 1 CPU / 3GB RAM
연결된 사용자 수
2 노드 - 1 CPU / 3GB RAM (노드 당)
연결된 사용자 수
2 노드 - 2 CPU / 6GB RAM (노드 당)
연결된 사용자 수
Hardware | Max Connected | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean |
---|---|---|---|---|---|---|
1 Node - 1 CPU / 3GB RAM | 19542 | 42.40 msec | 26.54 msec | 1340 / sec | 196.12 / sec | 34.21 msec |
2 Nodes - 1 CPU / 3GB RAM (each) | 27558 | 16.93 msec | 15.92 msec | 930 / sec | 161.52 / sec | 16.60 msec |
2 Nodes - 2 CPU / 6GB RAM (each) | 32092 | 20.17 msec | 18.18 msec | 1097.7 / sec | 187.82 / sec | 19.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 (노드 당)
처리량 (요청/초)
Hardware | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean |
---|---|---|---|---|---|
1 Node - 1 CPU / 3GB RAM | 29.07 msec | 20.10 msec | 849.6 / sec | 519.46 / sec | 24.60 msec |
2 Nodes - 1 CPU / 3GB RAM (each) | 31.65 msec | 20.01 msec | 1014.3 / sec | 672.18 / sec | 25.95 msec |
2 Nodes - 2 CPU / 6GB RAM (each) | 0.14 sec | 20.01 msec | 1160.8 / sec | 750.76 / sec | 28.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 (노드 당)
처리량 (요청/초)
Hardware | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean |
---|---|---|---|---|---|
1 Node - 1 CPU / 3GB RAM | 33.40 msec | 17.27 msec | 802.2 / sec | 499.63 / sec | 24.61 msec |
2 Nodes - 1 CPU / 3GB RAM (each) | 27.87 msec | 16.81 msec | 1035.5 / sec | 673.42 / sec | 22.19 msec |
2 Nodes - 2 CPU / 6GB RAM (each) | 76.85 msec | 16.95 msec | 1162 / sec | 776.77 / sec | 25.03 msec |
워크로드 4 - 사용자 지정 Lua RPC 호출 #
이 워크로드는 Lua 런타임을 통해 노출되는 간단한 RPC 함수를 실행합니다. 이 함수는 페이로드를 JSON 문자열로 수신하고 디코딩한 다음 발신자에게 다시 에코합니다.
1 노드 - 1 CPU / 3GB RAM
처리량 (요청/초)
2 노드 - 1 CPU / 3GB RAM (노드 당)
처리량 (요청/초)
2 노드 - 2 CPU / 6GB RAM (노드 당)
처리량 (요청/초)
Hardware | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean |
---|---|---|---|---|---|
1 Node - 1 CPU / 3GB RAM | 26.18 msec | 15.01 msec | 976.5 / sec | 633.42 / sec | 20.22 msec |
2 Nodes - 1 CPU / 3GB RAM (each) | 19.25 msec | 15.68 msec | 1192 / sec | 706.71 / sec | 17.48 msec |
2 Nodes - 2 CPU / 6GB RAM (each) | 20.27 msec | 16.11 msec | 1383.4 / sec | 823.55 / sec | 18.16 msec |
워크로드 5 - 사용자 지정 Go RPC 호출 #
이 워크로드는 Go 런타임을 통해 노출되는 간단한 RPC 함수를 실행합니다. 이 함수는 페이로드를 JSON 문자열로 수신하고 디코딩한 다음 발신자에게 다시 에코합니다.
1 노드 - 1 CPU / 3GB RAM
처리량 (요청/초)
2 노드 - 1 CPU / 3GB RAM (노드 당)
처리량 (요청/초)
2 노드 - 2 CPU / 6GB RAM (노드 당)
처리량 (요청/초)
Hardware | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean |
---|---|---|---|---|---|
1 Node - 1 CPU / 3GB RAM | 26.12 msec | 14.42 msec | 975.9 / sec | 635.36 / sec | 19.97 msec |
2 Nodes - 1 CPU / 3GB RAM (each) | 20.87 msec | 14.91 msec | 1205.7 / sec | 707.12 / sec | 17.29 msec |
2 Nodes - 2 CPU / 6GB RAM (each) | 20.19 msec | 15.59 msec | 1386.4 / sec | 820.41 / sec | 18.00 msec |
위에 표시된 것처럼 단일 Nakama 서버는 19.97msec(평균)로 제공되는 평균 최대 600 요청/초를 처리할 수 있습니다. 워크로드 5의 결과와 비교할 때 Lua와 Go 런타임 간의 결과가 매우 유사함을 알 수 있습니다. 이는 벤치마킹된 워크로드가 CPU 계산을 거의 일으키지 않기 때문이며 따라서 Lua 가상 머신의 차이에도 불구하고 결과가 비슷해집니다. CPU 집약적 코드를 사용하면 Lua 런타임의 RAM 사용량과 마찬가지로 성능 결과가 달라지기 시작합니다.
워크로드 6 - 사용자 지정 권한 보유 대결 논리 #
이 워크로드는 Nakama의 서버 권한 보유 멀티플레이어 엔진에서 실행되는 실시간 멀티플레이어 게임을 에뮬레이트합니다. 클라이언트와 사용자 지정 로직은 실제 멀티플레이어 게임이 아니지만 이 코드는 서버와 연결된 게임 클라이언트 간에 교환되는 메시지 측면에서 실제 사용 사례 시나리오의 근사치를 생성합니다. 이 워크로드에서 서버 및 클라이언트 로직에 대해 간략하게 설명합니다.
서버 측 로직 #
서버는 초당 10틱의 틱 속도로 멀티플레이어 대결을 실행합니다. 각 대결에는 최대 10명의 플레이어가 있을 수 있습니다.
서버는 클라이언트가 진행 중인 대결(플레이어 10명 미만)의 ID를 얻기 위해 쿼리할 수 있는 RPC 호출을 구현합니다. 이 API가 호출되면 서버는 대결 목록 기능을 사용하여 자리가 있는 대결을 찾고 첫 번째 결과를 반환합니다. 대결을 찾지 못한 경우 새 대결이 시작됩니다.
대결 루프 로직은 간단합니다. 서버는 클라이언트로부터 두 작업 코드 중 하나를 수신할 것으로 예상하고 다음 작업 중 하나를 수행합니다.
- 수신된 메시지를 클라이언트로 에코백합니다.
- 모든 대결 참가자에게 메시지를 브로드캐스트합니다.
클라이언트 측 로직 #
클라이언트 로직도 간단합니다. 각 게임 클라이언트는 다음 단계를 순서대로 수행합니다:
- 토큰을 받기 위해 Nakama로 기존 사용자를 인증합니다.
- 서버 RPC 함수를 실행하여 진행 중인 대결(자리가 있는)의 ID를 수신합니다.
- 실시간 API와 웹 소켓 연결을 설정합니다.
- 2단계에서 받은 아이디로 이 대결에 가입합니다.
- 180초 동안 클라이언트는 루프를 돌고 0.5초마다 작업 코드 1 또는 2가 포함된 메시지 전송을 번갈아 가며 수행합니다.
클라이언트가 보낸 메시지에는 각각 작업 코드 1 및 2에 대해 44자 및 35자의 문자열이 있는 고정 크기의 페이로드가 포함됩니다.
1 노드 - 1 CPU / 3GB RAM
연결된 사용자 수
2 노드 - 1 CPU / 3GB RAM (노드 당)
연결된 사용자 수
2 노드 - 2 CPU / 6GB RAM (노드 당)
연결된 사용자 수
이 결과는 이 워크로드가 관련되어 있기 때문에 클라이언트가 수행한 각 요청에 대한 평균입니다:
- 인증
- RPC 호출
- 웹 소켓 연결 및
- 웹 소켓 연결 통해 메시지 전송
결과에는 각 클라이언트 세션 내에서 수행되는 전체 요청 로직 집합이 고려됩니다.
Hardware | highest 10sec mean | lowest 10sec mean | Highest Rate | Mean Rate | Mean |
---|---|---|---|---|---|
1 Node - 1 CPU / 3GB RAM | 42.21 msec | 1.07 msec | 126.5 / sec | 36.72 / sec | 15.06 msec |
2 Nodes - 1 CPU / 3GB RAM (each) | 0.10 sec | 1.14 msec | 213.8 / sec | 54.68 / sec | 28.21 msec |
2 Nodes - 2 CPU / 6GB RAM (each) | 41.82 msec | 1.07 msec | 350 / sec | 85.82 / sec | 15.93 msec |
아래 표는 대결 중 교환되는 데이터 메시지와 함께 게임 서버가 처리하는 네트워크 처리량입니다. 클라이언트가 수신한 바이트 수가 전송된 바이트 수보다 훨씬 많다는 것을 알 수 있습니다. 클라이언트가 보낸 메시지의 50%는 위에서 언급한 대로 서버에서 모든 대결 참가자에게 브로드캐스트를 시작합니다.
Hardware | Sent/Received | Highest Rate | Total |
---|---|---|---|
1 Node - 1 CPU / 3GB RAM | Sent | 4.65 Mbits/sec | 157.92 MB |
Received | 24.88 Mbits/sec | 809.65 MB | |
2 Node - 1 CPU / 3GB RAM (each) | Sent | 5.90 Mbits/sec | 201.35 MB |
Received | 31.96 Mbits/sec | 1020.68 MB | |
2 Node - 2 CPU / 6GB RAM (each) | Sent | 7.64 Mbits/sec | 261.61 MB |
Received | 40.54 Mbits/sec | 1.30 GB |