# 基准

**URL:** https://heroiclabs.com/docs/zh/nakama/getting-started/benchmarks/
**Summary:** Performance benchmarks for Nakama on a number of different workloads for several of the core APIs, such as Concurrent User Count, New User Registration, Custom RPC calls, and authoritative multiplayer.

---


# 基准

在本次评估中，我们对Nakama的部分工作负载进行了基准测试，测试对象为几个核心API，这些API通常用于构建大型多人游戏。

这些工作负载已经在一组不同的硬件配置上运行，以展示Nakama的对现代硬件友好且高可扩展的架构带来的性能优势。

结果表明：Nakama的性能随着硬件规模的增长而增长。向上和向外扩展都提供了许多优势：从集群管理的简化，到获得总体上更好的硬件和规模经济，均包括在内。

## 方法

基准测试用强大的分布式负载测试工具[Tsung](http://tsung.erlang-projects.org/)执行。

Tsung工作负载在单节点部署（Nakama OSS）和集群模式（NakamaEnterprise）中使用单个数据库实例，在几种不同的配置中对Nakama进行基准测试。

数据库实例硬件在所有配置和工作负载中保持不变，以确保没有I/O瓶颈。尽管我们还测试了一些数据库绑定的API，但这些基准测试将关注Nakama的功能。

Tsung服务器在Google Compute Engine (GCE)上运行。Nakama OSS和Enterprise均在我们的[Heroic Cloud](https://cloud.heroiclabs.com)架构上运行。

在实际工作负载之前，并没有预热运行。

## 设置

### Tsung / 数据库

Tsung拓扑结构由一个主节点和20个从节点组成。此设置在所有基准测试运行中都保持不变，硬件规格为：

|                   | Tsung Main      | Tsung Redundant | 数据库
|---                |---              |---              |---
|实例类型      |n1-standard-32   |n1-standard-32   |dedicated-core vCPU
| vCPU / Mem        | 6 / 8GB         | 3 / 2GB         | 8 / 30GB
| IOPS (read/write) |-                |-                |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**

连接的用户数

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/connections/2-node-1-cpu-graphes-Users-simultaneous.svg" >}})

**2 节点 - 1 CPU / 3GB RAM（每节点）**

连接的用户数

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/connections/2-node-2-cpu-graphes-Users-simultaneous.svg" >}})

**2 节点 - 2 CPU / 6GB RAM（每节点）**

连接的用户数

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/connections/2-node-2-cpu-graphes-Users-simultaneous.svg" >}})

<table>
  <tr>
    Time to connect
  </tr>
  <tr>
    <th>Hardware</th>
    <th>Max Connected</th>
    <th>highest 10sec mean</th>
    <th>lowest 10sec mean</th>
    <th>Highest Rate</th>
    <th>Mean Rate</th>
    <th>Mean</th>
  </tr>
  <tr>
    <td>1 Node - 1 CPU / 3GB RAM</td>
    <td>19542</td>
    <td>42.40 msec </td>
    <td>26.54 msec</td>
    <td>1340 / sec</td>
    <td>196.12 / sec</td>
    <td>34.21 msec </td>
  </tr>
    <tr>
    <td>2 Nodes - 1 CPU / 3GB RAM (each)</td>
    <td>27558</td>
    <td>16.93 msec </td>
    <td>15.92 msec</td>
    <td>930 / sec</td>
    <td>161.52 / sec</td>
    <td>16.60 msec </td>
  </tr>
    <tr>
    <td>2 Nodes - 2 CPU / 6GB RAM (each)</td>
    <td>32092</td>
    <td>20.17 msec </td>
    <td>18.18 msec</td>
    <td>1097.7 / sec</td>
    <td>187.82 / sec</td>
    <td>19.15 msec </td>
  </tr>
</table>


如上所示，具有单个CPU内核的单个Nakama实例可以有多达~19500个连接用户。最多可扩展到2个节点，每个节点有2个CPU核，此值可达~32000 CCU。

### 工作负载2 - 注册新用户

此工作负载模拟通过游戏服务器的[设备身份验证](../../concepts/authentication/#device)API注册新用户，该API将新帐户存储到数据库中。

**1 节点 - 1 CPU / 3GB RAM**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/registrations/1-node-1-cpu-graphes-Transactions-rate.svg" >}})

**2 节点 - 1 CPU / 3GB RAM（每节点）**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/registrations/2-node-1-cpu-graphes-Transactions-rate.svg" >}})

**2 节点 - 2 CPU / 6GB RAM（每节点）**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/registrations/2-node-2-cpu-graphes-Transactions-rate.svg" >}})

<table>
  <tr>
    Request statistics
  </tr>
  <tr>
    <th>Hardware</th>
    <th>highest 10sec mean</th>
    <th>lowest 10sec mean</th>
    <th>Highest Rate</th>
    <th>Mean Rate</th>
    <th>Mean</th>
  </tr>
  <tr>
    <td>1 Node - 1 CPU / 3GB RAM</td>
		<td>29.07 msec </td>
		<td>20.10 msec</td>
		<td>849.6 / sec</td>
		<td>519.46 / sec</td>
		<td>24.60 msec </td>
  </tr>
  <tr>
    <td>2 Nodes - 1 CPU / 3GB RAM (each)</td>
		<td>31.65 msec </td>
		<td>20.01 msec</td>
		<td>1014.3 / sec</td>
		<td>672.18 / sec</td>
		<td>25.95 msec </td>
  </tr>
  <tr>
    <td>2 Nodes - 2 CPU / 6GB RAM (each)</td>
		<td>0.14 sec </td>
		<td>20.01 msec</td>
		<td>1160.8 / sec</td>
		<td>750.76 / sec</td>
		<td>28.46 msec </td>
  </tr>
</table>

如上所示，一台Nakama服务器可以处理平均约500个请求/秒的负载，在为新用户执行数据库写入操作时，请求以24.60毫秒（平均值）送达。按照这个速度，一个游戏每小时可以创建186万个新玩家。当扩展到2个节点时，该值将达到每小时270万个玩家账户。

### 工作负载3 — 对用户进行身份验证

此工作负载包括使用游戏服务器的[设备身份验证](../../concepts/authentication/#device)API对现有用户进行身份验证。

**1 节点 - 1 CPU / 3GB RAM**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/login/1-node-1-cpu-graphes-Transactions-rate.svg" >}})

**2 节点 - 1 CPU / 3GB RAM（每节点）**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/login/2-node-1-cpu-graphes-Transactions-rate.svg" >}})

**2 节点 - 2 CPU / 6GB RAM（每节点）**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/login/2-node-2-cpu-graphes-Transactions-rate.svg" >}})

<table>
  <tr>
    Request statistics
  </tr>
  <tr>
    <th>Hardware</th>
    <th>highest 10sec mean</th>
    <th>lowest 10sec mean</th>
    <th>Highest Rate</th>
    <th>Mean Rate</th>
    <th>Mean</th>
  </tr>
  <tr>
    <td>1 Node - 1 CPU / 3GB RAM</td>
		<td>33.40 msec </td>
		<td>17.27 msec</td>
		<td>802.2 / sec</td>
		<td>499.63 / sec</td>
		<td>24.61 msec </td>
  </tr>
  <tr>
     <td>2 Nodes - 1 CPU / 3GB RAM (each)</td>
		<td>27.87 msec </td>
		<td>16.81 msec</td>
		<td>1035.5 / sec</td>
		<td>673.42 / sec</td>
		<td>22.19 msec </td>
  </tr>
  <tr>
    <td>2 Nodes - 2 CPU / 6GB RAM (each)</td>
		<td>76.85 msec </td>
		<td>16.95 msec</td>
		<td>1162 / sec</td>
		<td>776.77 / sec</td>
		<td>25.03 msec </td>
  </tr>
</table>

### 工作负载4 - 自定义Lua RPC调用

此工作负载执行通过Lua运行时公开的简单[RPC函数](../../server-framework/introduction/#functionality)。该函数接收JSON字符串形式的有效负载，对其进行解码，并将其回传给发送方。

**1 节点 - 1 CPU / 3GB RAM**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/rpc-lua/1-node-1-cpu-graphes-Transactions-rate.svg" >}})

**2 节点 - 1 CPU / 3GB RAM（每节点）**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/rpc-lua/2-node-1-cpu-graphes-Transactions-rate.svg" >}})

**2 节点 - 2 CPU / 6GB RAM（每节点）**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/rpc-lua/2-node-2-cpu-graphes-Transactions-rate.svg" >}})

<table>
  <tr>
    Request statistics
  </tr>
  <tr>
    <th>Hardware</th>
    <th>highest 10sec mean</th>
    <th>lowest 10sec mean</th>
    <th>Highest Rate</th>
    <th>Mean Rate</th>
    <th>Mean</th>
  </tr>
  <tr>
    <td>1 Node - 1 CPU / 3GB RAM</td>
		<td>26.18 msec </td>
		<td>15.01 msec</td>
		<td>976.5 / sec</td>
		<td>633.42 / sec</td>
		<td>20.22 msec </td>
  </tr>
  <tr>
    <td>2 Nodes - 1 CPU / 3GB RAM (each)</td>
		<td>19.25 msec </td>
		<td>15.68 msec</td>
		<td>1192 / sec</td>
		<td>706.71 / sec</td>
		<td>17.48 msec </td>
  </tr>
  <tr>
    <td>2 Nodes - 2 CPU / 6GB RAM (each)</td>
		<td>20.27 msec </td>
		<td>16.11 msec</td>
		<td>1383.4 / sec</td>
		<td>823.55 / sec</td>
		<td>18.16 msec </td>
  </tr>
</table>

### 工作负载5 - 自定义Go RPC调用

此工作负载执行通过Go运行时公开的简单[RPC函数](../../server-framework/introduction/#functionality)。该函数接收JSON字符串形式的有效负载，对其进行解码并将其回传给发送方。

**1 节点 - 1 CPU / 3GB RAM**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/rpc-go/1-node-1-cpu-graphes-Transactions-rate.svg" >}})

**2 节点 - 1 CPU / 3GB RAM（每节点）**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/rpc-go/2-node-1-cpu-graphes-Transactions-rate.svg" >}})

**2 节点 - 2 CPU / 6GB RAM（每节点）**

吞吐量（请求/秒）

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/rpc-go/2-node-2-cpu-graphes-Transactions-rate.svg" >}})

<table>
  <tr>
    Request statistics
  </tr>
  <tr>
    <th>Hardware</th>
    <th>highest 10sec mean</th>
    <th>lowest 10sec mean</th>
    <th>Highest Rate</th>
    <th>Mean Rate</th>
    <th>Mean</th>
  </tr>
  <tr>
    <td>1 Node - 1 CPU / 3GB RAM</td>
		<td>26.12 msec </td>
		<td>14.42 msec</td>
		<td>975.9 / sec</td>
		<td>635.36 / sec</td>
		<td>19.97 msec </td>
  </tr>
  <tr>
    <td>2 Nodes - 1 CPU / 3GB RAM (each)</td>
		<td>20.87 msec </td>
		<td>14.91 msec</td>
		<td>1205.7 / sec</td>
		<td>707.12 / sec</td>
		<td>17.29 msec </td>
  </tr>
  <tr>
    <td>2 Nodes - 2 CPU / 6GB RAM (each)</td>
		<td>20.19 msec </td>
		<td>15.59 msec</td>
		<td>1386.4 / sec</td>
		<td>820.41 / sec</td>
		<td>18.00 msec </td>
  </tr>
</table>

如上所示，一台Nakama服务器平均可以在19.97毫秒（平均）内处理约600个请求/秒。当与工作负载5的结果进行比较时，我们发现Lua和Go运行时之间的结果非常相似。这是因为被基准测试的工作负载不会引起大量的CPU计算；使得尽管Lua虚拟机存在差异，结果仍然相似。对于CPU密集型代码，性能结果将有所不同，Lua运行时的RAM使用情况也会不同。


### 工作负载6 - 自定义权威比赛逻辑

此工作负载模拟在Nakama的[服务器权威多人游戏](../../concepts/multiplayer/authoritative/)引擎上运行的实时多人游戏。尽管客户端和自定义逻辑不是实际的多人游戏；从服务器和连接的游戏客户端之间交换的消息的角度，该代码创建了近似的真实用例场景。我们将简单介绍此工作负载中的服务器和客户端逻辑。

#### 服务器端逻辑

服务器以每秒10次节拍率运行多人比赛。每场比赛最多可有10个玩家。

服务器实现了一个RPC调用，客户端可以查询该调用以获得正在进行的比赛（少于10名玩家）的ID。当调用此API时，服务器将使用[列出比赛](../../concepts/multiplayer/match-listing/)功能查找未满的比赛并返回第一个结果。如未找到比赛，则开始一个新的比赛。

比赛循环逻辑很简单；服务器期望从客户端接收两个操作码中的一个，并执行以下任一操作：

1. 将收到的消息回显给客户端。
2. 将消息广播给所有的比赛参与者。

#### 客户端逻辑

客户端逻辑也很简单；每个游戏客户端按顺序执行以下步骤：

1. 对现有用户进行Nakama身份验证以接收令牌。
2. 执行服务器RPC函数以接收正在进行的比赛（未满）的ID。
3. 建立与实时API的网络套接字连接。
4. 使用步骤2中收到的ID加入比赛。
5. 客户端将循环180秒，每半秒将交替发送一条操作码为1或2的消息。

客户端发送的消息包含固定大小的有效负载，操作码1和2分别为44和35个字符。

**1 节点 - 1 CPU / 3GB RAM**

连接的用户数

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/authoritative-match/1-node-1-cpu-graphes-Users-simultaneous.svg" >}})

**2 节点 - 1 CPU / 3GB RAM（每节点）**

连接的用户数

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/authoritative-match/2-node-1-cpu-graphes-Users-simultaneous.svg" >}})

**2 节点 - 2 CPU / 6GB RAM（每节点）**

连接的用户数

![基准寄存器]({{< fingerprint_image "/images/pages/nakama/getting-started/benchmarks/authoritative-match/2-node-2-cpu-graphes-Users-simultaneous.svg" >}})

这些结果是客户端发出的每个请求的平均值，因为此工作负载涉及：

1. 身份验证
2. RPC调用
3. 连接到网络套接字和
4. 通过网络套接字连接发送消息；

结果考虑了在每个客户端会话中执行的整个请求逻辑集。

<table>
  <tr>
    Request statistics
  </tr>
  <tr>
    <th>Hardware</th>
    <th>highest 10sec mean</th>
    <th>lowest 10sec mean</th>
    <th>Highest Rate</th>
    <th>Mean Rate</th>
    <th>Mean</th>
  </tr>
  <tr>
    <td>1 Node - 1 CPU / 3GB RAM</td>
		<td>42.21 msec </td>
		<td>1.07 msec</td>
		<td>126.5 / sec</td>
		<td>36.72 / sec</td>
		<td>15.06 msec </td>
  </tr>
  <tr>
    <td>2 Nodes - 1 CPU / 3GB RAM (each)</td>
		<td>0.10 sec </td>
		<td>1.14 msec</td>
		<td>213.8 / sec</td>
		<td>54.68 / sec</td>
		<td>28.21 msec </td>
  </tr>
  <tr>
    <td>2 Nodes - 2 CPU / 6GB RAM (each)</td>
		<td>41.82 msec </td>
		<td>1.07 msec</td>
		<td>350 / sec</td>
		<td>85.82 / sec</td>
		<td>15.93 msec </td>
  </tr>
</table>

下表包括游戏服务器利用比赛中交换的数据消息处理的网络吞吐量。可见，客户端接收的字节数远高于发送的字节数；如上所述，客户端发送的50%的消息由服务器广播给所有比赛参与者。

<table>
  <tr>
    Network Throughput
  </tr>
  <tr>
    <th>Hardware</th>
    <th>Sent/Received</th>
    <th>Highest Rate</th>
    <th>Total</th>
  </tr>
  <tr>
    <td style="border-right: .05rem solid rgba(0,0,0,.07);">1 Node - 1 CPU / 3GB RAM</td>
    <td>Sent</td>
		<td>4.65 Mbits/sec</td>
		<td>157.92 MB</td>
  </tr>
  <tr>
    <td style="border-top: 0; border-right: .05rem solid rgba(0,0,0,.07);"></td>
    <td>Received</td>
		<td>24.88 Mbits/sec</td>
		<td>809.65 MB</td>
  </tr>
  <tr>
    <td style="border-right: .05rem solid rgba(0,0,0,.07);">2 Node - 1 CPU / 3GB RAM (each)</td>
    <td>Sent</td>
		<td>5.90 Mbits/sec</td>
		<td>201.35 MB</td>
  </tr>
  <tr>
    <td style="border-top: 0; border-right: .05rem solid rgba(0,0,0,.07);"></td>
    <td>Received</td>
		<td>31.96 Mbits/sec</td>
		<td>1020.68 MB</td>
  </tr>
  <tr>
    <td style="border-right: .05rem solid rgba(0,0,0,.07);">2 Node - 2 CPU / 6GB RAM (each)</td>
    <td>Sent</td>
		<td>7.64 Mbits/sec</td>
		<td>261.61 MB</td>
  </tr>
  <tr>
    <td style="border-top: 0; border-right: .05rem solid rgba(0,0,0,.07);"></td>
    <td>Received</td>
		<td>40.54 Mbits/sec</td>
		<td>1.30 GB</td>
  </tr>
</table>
