---
title: リアルタイムゲームサーバーのベンチマークをとる方法
tags: 
author: [Kengo Nakajima](https://www.docswell.com/user/kengonakajima)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/4JQX2GDLEP.jpg?width=480
description: マシンやTCP/IPの低いレイヤーから順番にベンチマークを測定して、迷わずに必要な結果を早く得る方法を説明します。
published: February 08, 23
canonical: https://www.docswell.com/s/kengonakajima/5777V5-2023-02-08-141725
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/4JQX2GDLEP.jpg)

リアルタイムゲームサーバーの
ベンチマークをとる方法
(株)モノビット 取締役CTO 中嶋謙互


# Page. 2

![Page Image](https://bcdn.docswell.com/page/K746L5Z5E1.jpg)

ベンチマークの失敗パターン
•
マシンやネットワーク環境の性能を詳しく調べずに
ミドルウェアやアプリケーションの性能を測定し、
意外な結果が出てしまい、原因がわからず混乱する
ミドルウェアは、ハードウェアの性能以上の性能を実現できない。
アプリケーションは、ミドルウェアの性能以上の性能を実現できない。


# Page. 3

![Page Image](https://bcdn.docswell.com/page/LJ1VLWR2EG.jpg)

ベンチマークの手順
1.測定に使うハードウェアを用意する
2.ハードウェアの性能を測定する
3.ミドルウェアの性能を測定する
4.(アプリケーションの性能を測定する)
本資料ではおもに1~3を説明します。
2で納得できたら3へ、3で納得できたら4へと進むのが重要


# Page. 4

![Page Image](https://bcdn.docswell.com/page/GJWLV612E2.jpg)

性能の指標
•
スループット速度 : ビット/秒 または メッセージ/秒
•
応答速度 : 秒
•
同時接続数 : 本


# Page. 5

![Page Image](https://bcdn.docswell.com/page/4EZM4YP4J3.jpg)

用意するマシンのタイプ
•
2または4コア、4または8GBRAMの汎用マシンがMRSに最適
•
•
AWS
•
日本ではm4/c4.largeまたはxlarge
•
日本以外ではm5/c5 のlargeまたはxlarge
IDCFクラウド
•
•
M4,M8,L8など
GCE
•
n1-standard-2または standard-4など


# Page. 6

![Page Image](https://bcdn.docswell.com/page/Y76N3DMG7V.jpg)

マシン構成
クライアント用
インスタンス1
m4.xlarge
サーバー用
インスタンス
m4.xlarge
クライアント用
インスタンス1
m4.xlarge
・・・
同じアベイラビリティゾーン(ロケーション)内に設置すること。
サーバー用を1台とし、
クライアント用は1台から始めて必要に応じて増やしていく


# Page. 7

![Page Image](https://bcdn.docswell.com/page/G755L3ZX74.jpg)

AWSにおける通信帯域制限(実測)
•
各インスタンスにおいて
• m4,c4シリーズ(xlarge) : 1.2Gbps
• m5,c5シリーズ(xlarge) : 8Gbps
iperf3などの標準ツールおよび
独自開発した libuv_bench, mrs_room_bench等のプログラムを使用。
m5,c5シリーズは東京ではまだ使用不可(2017)


# Page. 8

![Page Image](https://bcdn.docswell.com/page/9J2NLZRQER.jpg)

AWSにおけるパケット数制限(実測)
•
各インスタンスにおいて
• m4,c4シリーズ(xlarge)
• 送受信合計15万 packets/sec
• m5,c5シリーズ(xlarge)
• 送受信合計92万、片道55万 packets/sec
iperf3などの標準ツールおよび
独自開発した libuv_bench, mrs_room_bench等のプログラムを使用
m5,c5シリーズは東京ではまだ使用不可(2017)


# Page. 9

![Page Image](https://bcdn.docswell.com/page/DEYPQRDYEM.jpg)

AWS以外における制限
•
Google Compute
7~8Gbpsらしい
IDCFクラウド
• 1.9Gbps (実測), 40万パケット/sec
他
• 環境や条件によりさまざま
•
•
•
多くのクラウドでは物理的に10Gbps Ethernetが使われているが、
そのワイヤスピードよりも低い制限がかかっている。


# Page. 10

![Page Image](https://bcdn.docswell.com/page/VJN5KD6R78.jpg)

ハードウェアの性能を測定(iperf3)
インストール
sudo yum install iperf3
サーバーを起動
クライアントを起動
iperf3 -s
iperf3 -c 10.6.0.199
サーバー用
インスタンス
m4.xlarge
10.6.0.199
クライアントから
サーバに負荷をかける
クライアント用
インスタンス1
m4.xlarge
10.6.0.135
NICが複数ある場合は、LAN通信用のIPアドレスを指定する必要がある。
172. や10. ではじまるアドレスはだいたいLAN用


# Page. 11

![Page Image](https://bcdn.docswell.com/page/YE9YVGLZJ3.jpg)

iperf3の結果 (TCP) @IDCFクラウド
IDCFクラウド L8での測定結果 (以下同様)
サーバー。だいたい2Gbps受信
クライアント だいたい2Gbps送信
TCPはLinuxの輻輳制御アルゴリズムが使われるので、
特にオプションを設定しなくても自動的に可能な最高速度で送信される


# Page. 12

![Page Image](https://bcdn.docswell.com/page/GE86PVWY7D.jpg)

iperf3の結果 (UDP、安定)
サーバー。だいたい2Gbps受信
iperf3 -s 2&gt;&amp;1 | grep -v ORDER
受信側(サーバー)でUDPのOUT OF ORDERログメッセージが
大量に出力されるため、それ以外だけを表示。
OUT OF ORDERが全く出ないならそれがのぞましい。
AWSなら少ない。時間帯によっても異なる
※IDCFクラウド L8での測定結果
クライアント だいたい2Gbps送信
-u -b 2000M
-uでUDPを選択。
UDPは輻輳制御が働かないので、
どれだけの量を送信するかオプションで設定する。
上図では 2000Mbps


# Page. 13

![Page Image](https://bcdn.docswell.com/page/LEL915N9JR.jpg)

iperf3の結果 (UDP、不安定)
サーバー。受信量が4000Mbps(4Gbps)より小さいうえ、
一定していない。 Lostパケットも数千個づつ発生
※IDCFクラウド L8での測定結果
クライアント -b 4000Mで 4Gbps送信するよう設定したが、
実際送信できた量はそれよりだいぶん小さい


# Page. 14

![Page Image](https://bcdn.docswell.com/page/4JMZW3XVEW.jpg)

iperf3の結果 (TCP、小パケット)
TCPで1バイトづつ書き込み (-l 1オプション)した場合、
7Mbpsしか出ていないが
これで正常(良好)な結果だと言える。
TCPで32バイトづつ書き込み。200Mbps程度に向上
※IDCFクラウド L8での測定結果


# Page. 15

![Page Image](https://bcdn.docswell.com/page/PJR6YQNW79.jpg)

TCPパケットのサイズを確認する
tcpdump -i ens160 tcp port 5201 -c 100
•
サーバ側においてtcpdumpコマンドを使い、iperf3が
使うTCP5201番のポートについて、100パケット分の
記録を取る。
※IDCFクラウド L8での測定結果


# Page. 16

![Page Image](https://bcdn.docswell.com/page/PEXMG5NV7X.jpg)

TCPパケットのサイズ
iperf3 -c 10.6.0.199 -l 1
iperf3は、writeシステムコールでTCPソケットに1バイトづつ書き込む。
Linux OSは、1バイトづつ書き込まれても、
一定時間以内の書き込みについては1つのパケットにまとめてしまう。
iperf3 -c 10.6.0.199 -l 1 —no-delay
—no-delayオプションを付けると、パケットサイズがかなり小さくなっているのがわかる
※IDCFクラウド L8での測定結果


# Page. 17

![Page Image](https://bcdn.docswell.com/page/3EKG46N5JD.jpg)

iperf3の結果 (UDP、小パケット)
-l 1で1バイトづつ送信。
UDPのサーバ側の出力。 1バイトづつの送信では、
2Mbps程度しか出ない
-l 32 -b 100M で32バイトづつ送信。
100Mbps近いが、
ロス率が10%越えて不安定になっている。
これ以上速くは送れない
※IDCFクラウド L8での測定結果


# Page. 18

![Page Image](https://bcdn.docswell.com/page/L73NL6V175.jpg)

UDPパケットのサイズ
iperf3 -c 10.6.0.199 -u -l 1
UDPでは、1バイトのペイロードをもつUDPデータグラムだけが送られている
※IDCFクラウド L8での測定結果


# Page. 19

![Page Image](https://bcdn.docswell.com/page/87DWNV8KJG.jpg)

パケットサイズとスループットの関係
•
アプリケーションデータの前後にヘッダなどが大量に付いているため、Ethernetおよ
びIPネットワークでは、パケットサイズが小さいとスループットは大幅に落ちる
•
参考:
•
•
http://blogs.itmedia.co.jp/komata/2011/04/udp-8fa9.html
IPv4における最大パケットサイズ(MTU)は1500バイトのことが多い
•
OSの設定による


# Page. 20

![Page Image](https://bcdn.docswell.com/page/VJP95V83E8.jpg)

ジャンボフレーム
•
1500より大きいMTU設定をジャンボフレームと呼ぶ
•
典型的には9000または9001バイト
•
AWS
•
•
Amazon Linux : デフォルトでJumboフレーム有効(9001)
•
CentOS 7: t2シリーズでは自動的に9001になる
IDCFクラウド
•
CentOS 7
•
•
デフォルトでJumboフレーム無効 (1500)
上記以外
•
未調査


# Page. 21

![Page Image](https://bcdn.docswell.com/page/2EVMPZNNEQ.jpg)

MTUをifconfigで確認
Linode CentOS 7.3
デフォルトインストール
AWS CentOS 7.4
または AmazonLinux 2017.9
デフォルトインストール


# Page. 22

![Page Image](https://bcdn.docswell.com/page/57GGP4K57L.jpg)

ゲームサーバーではジャンボフレームは不要
•
ほとんどのパケットは、20バイト〜300バイト程度のちいさなパケット
•
ただし、たまにキャラのJSONデータが50KBとかまとめて送ることはある
•
通信相手は、インターネットに散らばる何千という異なるホスト
•
上記のような用途ではジャンボフレームは必要ない


# Page. 23

![Page Image](https://bcdn.docswell.com/page/4EQX2GNL7P.jpg)

パケットが小さいとCPU消費が大幅に大きい
大パケットの場合
iperf3 -c 10.6.0.199
TCPで、2Gbps送信中(MTU=1500)。
CPU消費は全部で0.3%と非常に小さい
小パケットの場合
iperf3 -c 10.6.0.199 -l 1 —no-delay
TCPで、1バイトづつ、
10Mbps程度を送信中。
CPU消費は全部で25%を越えている。
パケット数が多いと、
80倍以上負荷がかかっている。
原因はパケットの数が多いため
※IDCFクラウド L8での測定結果


# Page. 24

![Page Image](https://bcdn.docswell.com/page/KJ46L5G571.jpg)

毎秒のパケット数を調査する
•
pktcnt.rb という簡単なスクリプトを使う
•
https://gist.github.com/kengonakajima/5a898c926ea5d6fd12428800f4718a1a
現在時刻
unixtime
送信パケット数
合計パケット数
送信バイト数
受信バイト数
合計バイト数
平均パケット
サイズ
受信パケット数
UDPで200バイトのデータで負荷をかけてみた場合。
ヘッダの分少し大きくなっている
nethogsやdstatなどを併用してもOK


# Page. 25

![Page Image](https://bcdn.docswell.com/page/LE1VLWD27G.jpg)

ハードウェアの動作特性について
だいたいわかったところで、
それより上位の層について調べ始める


# Page. 26

![Page Image](https://bcdn.docswell.com/page/GEWLV6Y272.jpg)

MRSの性能を測定する2つのツール
•
•
mrs_bench : MRSのエコー性能を測定
mrs_room_bench : ルームサーバー性能を測定


# Page. 27

![Page Image](https://bcdn.docswell.com/page/47ZM4YX4E3.jpg)

mrs_bench
サーバーを起動
クライアントを起動
./sv
./cl 10.6.0.199 5 10
クライアントから
送ったデータが
サーバー用
インスタンス
m4.xlarge
10.6.0.199
おうむ返し(ECHO)される
クライアント用
インスタンス1
m4.xlarge
10.6.0.135
NICが複数ある場合は、LAN通信用のIPアドレスを指定する必要がある。
172. や10. ではじまるアドレスはだいたいLAN用


# Page. 28

![Page Image](https://bcdn.docswell.com/page/YJ6N3D4GJV.jpg)

mrs_bench の使い方
•
•
•
配布物はサーバとクライアントの両方を含む
ビルド方法と起動方法
• 詳細は mrs_bench/README.md
を参照
• 重要なクライアント起動時引数
• ./cl 10.6.0.199 10 1000 —size=40 —udp
10.6.0.199のサーバに対して同時10接続、1000ミリ秒に1回40バイトをUDPで送
信。
• サーバは引数なしで起動 (iperf3と同様)
評価版の注意点
• 最大接続数が100に制限されている


# Page. 29

![Page Image](https://bcdn.docswell.com/page/GJ55L3QXJ4.jpg)

mrs_bench の出力凡例
現在時刻
unixtime
•
•
ループ回数
送信回数
受信回数(過去1秒)
同時接続数
切断数
エラー数
受信Miバイト数
(過去1秒)
往復時間
平均ms
最大ms
ログに小文字の”c”が連続するのは、接続に成功したしるし dは切断 eはエラー
性能評価
•
受信バイト数 : recvBのカッコ内、例の(0.3)が通信スループット Mbytes/secを示す。
Mbit/sは単純にこの値の8倍
•
受信メッセージ数: recvNの (9532)などが1秒間のメッセージ数を示す
•
RTTが通信遅延を示す
最小ms
最新ms


# Page. 30

![Page Image](https://bcdn.docswell.com/page/LE3NL6V4E5.jpg)

mrs_benchのスループット(TCP)
コマンドライン
recvN
recvB (MiB)
スループット
Mbit/sec
ipv4 pkts/sec
send+recv
./cl 10.6.0.199 10 1
約9500
0.3
2.4Mbps
19100
./cl 10.6.0.199 100 1
約95000
2.9
19.2Mbps
190000
./cl 10.6.0.199 100 1 —size=100
約94000
10.1
80.8Mbps
190000
./cl 10.6.0.199 100 1 —size=500
約94000
45
360Mbps
190000
./cl 10.6.0.199 100 1 —size=1000
約93000
90
720Mbps
190000
./cl 10.6.0.199 100 1 —size=2000
約89000
177
1.4Gbps
375000
./cl 10.6.0.199 100 1 —size=3000
約89000
247
1.97Gbps
400000
./cl 10.6.0.199 100 1 —size=4000
不定
不定
不定
400000
size=3000より大きくするとエラーが増えて、結果が不安定になる。
1.97Gbpsで、かつ40万パケット/秒 という出力は
iperf3で測定したハードウェア限界に一致。
MRSがこのマシン環境での制限速度いっぱいまで使い切った
※IDCFクラウド L8での測定結果


# Page. 31

![Page Image](https://bcdn.docswell.com/page/8EDWNV857G.jpg)

mrs_benchのスループット(UDP)
コマンドライン
recvN
recvB (MiB)
スループット Mbit/sec
ipv4 pkt/sec
クライアント
プロセス数
サーバ
プロセス数
./cl 10.6.0.199 10 1 —udp
約9400
0.3
2.4Mbps
36900
1
1
./cl 10.6.0.199 100 1 —udp
約95000
2.9
19.2Mbps
263000
1
1
./cl 10.6.0.199 10 1 —udp —size=1000
約9400
9.1
72.8Mbps
59000
1
1
./cl 10.6.0.199 10 1 —udp —size=2000
約9300
18
144Mbps
96000
1
1
./cl 10.6.0.199 10 1 —udp —size=3000
約9300
27
236Mbps
135000
1
1
./cl 10.6.0.199 10 1 —udp —size=4000
約9300
35
280Mbps
177000
1
1
./cl 10.6.0.199 50 1 —udp —size=100 —port=xxx
約44000
4.8x2
38.4x2
合計335000
2
2
./cl 10.6.0.199 50 1 —udp —size=100 —port=xxx
不定
不定
不定
約380000
3
3
UDPはCPU消費が多いので、 --port設定を使って
プロセスの数を増やして測定する。
iperf3で測定した40万パケット/secに近づくと不安定になり測定できなくなる。
※IDCFクラウド L8での測定結果


# Page. 32

![Page Image](https://bcdn.docswell.com/page/V7P95V8DJ8.jpg)

パケット数とメッセージサイズ
•
MTU=1500で2KB送る時 (TCP)
送信側
受信側
seq=0
1500bytes
seq=1
500bytes
seq=0
ACK
seq=1
ACK
データを2個送信し、ACKを2個受信する。
合計4つのパケット処理が行われる。
送信と受信両方の合計数によって
制限されることに注意!


# Page. 33

![Page Image](https://bcdn.docswell.com/page/2JVMPZNGJQ.jpg)

パケット数とメッセージサイズ
•
MTU=1500で2KB送る時 (TCP, piggy back)
送信側
受信側
seq=0
1500bytes
seq=1
500bytes
seq=x
1500bytes
seq=1
ACK
seq=0
ACK
TCPには、一定時間以内のデータパケットと
ACKパケットをひとつにまとめて、
全体のパケット数を減らす機能が搭載されている。
そのため、合計パケット数は、
送信したデータパケットの2倍に単純にはならない。


# Page. 34

![Page Image](https://bcdn.docswell.com/page/5EGGP45DEL.jpg)

パケット数とメッセージサイズ
•
RUDP で2KB送る時 MTU=576
送信側
受信側
seq=0
576bytes
seq=1
576bytes
seq=2
576bytes
seq=3
272bytes
seq=0
ACK
seq=1
ACK
seq=2
ACK
seq=3
ACK
MRSでは、RUDPの「パスMTUブラックホール」
を回避するためにMTUを576に固定している。
そのため、2KB送るときに合計8個のパケットが送信される。
TCPに比べてパケットの数が2倍になっている。
またRUDPにはpiggy back機能はない
RUDPのパケット数は、
TCPのだいたい1.5倍〜2倍


# Page. 35

![Page Image](https://bcdn.docswell.com/page/4JQX2GZXEP.jpg)

mrs_benchの暗号化能力
•
MRSのブロック暗号アルゴリズム(AES)は、一般的な
XeonなどのCPUの1コアあたり約30~60Mbytes/secの
処理能力を持つ。


# Page. 36

![Page Image](https://bcdn.docswell.com/page/K746L532E1.jpg)

mrs_benchのスループット(TCP+暗号)
コマンドライン
recvN
recvB (MiB)
スループット Mbit/sec
サーバCPU
1スレッドの専有度
クライアント
プロセス数
サーバ
プロセス数
./cl 10.6.0.199 10 1 —encrypt
約9400
0.3
2.4Mbps
5%
1
1
./cl 10.6.0.199 10 1 —encrypt —size=1000
約9400
9.1
72.8Mbps
35%
1
1
./cl 10.6.0.199 10 1 —encrypt —size=2000
約9300
18
144Mbps
68%
1
1
./cl 10.6.0.199 10 1 —encrypt —size=3000
約9300
24
192Mbps
82%
1
1
./cl 10.6.0.199 10 1 —encrypt —size=4000
不定
不定
不定
99%
1
1
IDCFのL8マシンでは、1プロセス(1スレッド)では約200Mbps
(送受信の両方を暗号化しているので、2倍の400Mbps)
が限界となっていることがわかる
※IDCFクラウド L8での測定結果


# Page. 37

![Page Image](https://bcdn.docswell.com/page/LJ1VLW1KEG.jpg)

ゲームにおける暗号通信の必要性
•
必要 (トラフィックの5%以下)
•
•
ログイン認証、ショップ、アチーブメントなど
不必要
•
(トラフィックの95%以上)
MOBの座標更新、カメラ向き更新、GUIイベント送信、ボ
イスチャットデータなど
MRSでは、パケットごとに暗号の有効・無効を制御できるため、
通信の負荷容量設計においては暗号通信によるCPU消費増大は無視してよい。


# Page. 38

![Page Image](https://bcdn.docswell.com/page/GJWLV68PE2.jpg)

サーバー性能の飽和状態を知る方法
•
•
•
•
プロセスごとの飽和状態
マシン全体の飽和状態
どちらもtopで見る : CPU %
TCPの場合 : netstatで見る
暗号化したり、メッセージを極端に小さくしたりすると
環境による通信の速度制限に到達する前に
サーバーの性能は飽和する。


# Page. 39

![Page Image](https://bcdn.docswell.com/page/4EZM4Y86J3.jpg)

作業風景 topとpktcntを常に表示
サーバー側マシンtop
クライアント側マシンtop
pktcnt.rbパケット数出力
サーバープロセスログ
クライアントプロセスログ


# Page. 40

![Page Image](https://bcdn.docswell.com/page/Y76N3DPL7V.jpg)

topの見方 一つのsvプロセスが飽和
マシン全体の
負荷は 22.3 + 2.7 =
25%程度
svプロセスの負荷が100%
これはCPUコア1個(1スレッド分)を使い切っていることを示す。
これ以上このプロセスの性能は上がらない。
このマシンは4コアなので、同様のsvをあと3個増やせば性能は4倍になる。
MRSリアルタイムサーバーの場合は、だいたい単純計算でOK


# Page. 41

![Page Image](https://bcdn.docswell.com/page/G755L3KM74.jpg)

topの見方 svが8個ある場合
マシン全体の
負荷はここでわかる。
合計で85%に近く、
そろそろ飽和している
サーバーが8プロセス起動していて、
CPUはそれぞれ50%程度
4コアマシンなので、だいたい飽和してるとわかる


# Page. 42

![Page Image](https://bcdn.docswell.com/page/9J2NLZWRER.jpg)

TCPはnetstatも参考にできる
TCPでは、
netstat -tan | grep 33333
などとして接続の状態を監視できる。
受信バッファも送信バッファも
ほとんどたまっていない。
受信バッファが大量にたまっていて、
送信はたまっていない。
これはサーバー側の結果なので、
サーバーの性能が飽和しているとわかる
localアドレス
受信バッファ量
送信バッファ量
リモートアドレス
接続の状態


# Page. 43

![Page Image](https://bcdn.docswell.com/page/DEYPQRL5EM.jpg)

サーバーの性能が飽和しない時
•
接続数を増やしてもサーバーのCPU消費量が上がらなくなったら？
•
だいたいの場合はクライアントの性能が飽和している。
•
•
TCPであればnetstatのrecv-qがクライアント側で貯まる。
•
UDPであればクライアントの送信エラーが表示される。
よりコア数の多いマシンを使うか、マシンを増やして解決。


# Page. 44

![Page Image](https://bcdn.docswell.com/page/VJN5KD4478.jpg)

mrs_room_bench
•
•
MRSを用いて実装されたリアルタイム同期サーバー
のmrs_roomをベンチマークするためのクライアン
トプログラム
ベンチマーク対象となる mrs_roomのサーバープロ
グラムも mrs_room_benchに含まれている(バージョ
ン不一致を防ぐため)


# Page. 45

![Page Image](https://bcdn.docswell.com/page/YE9YVGQ4J3.jpg)

マルチプレイゲームの全体構成
ステップ1:接続先Room
2.双方向リアルタイム通信
Internet
Web-0
・・・
Web-n
Room-0
Room-1
・・・
Room-n
DB
Webサーバー部
リアルタイムサーバー部
(mrs_room)


# Page. 46

![Page Image](https://bcdn.docswell.com/page/GE86PVGV7D.jpg)

mrs_room の機能
1.ひとつのクライアントからUDPまたはTCPのデータ(パケット)を受信する
2.複数のクライアントに対してそのパケットを転送する
3.「部屋(ルーム)」の単位でそれを行う
4.1つのサーバープロセスが多数のルームを管理する
B
data
A
data
サーバープロセス
data
C
data
D


# Page. 47

![Page Image](https://bcdn.docswell.com/page/LEL915GRJR.jpg)

mrs_room における送信パターン
• 標準
: 自分も含めて全員に送る
• othercast : 自分以外に送る
• manycast : 指定した複数に送る
• unicast : 指定した相手だけに送る
• ownercast : 部屋の所有者だけに送る
• 拡張する場合
• nearcast : 近くの相手だけに送る
• condcast : 条件を満たす相手だけに送る
• etc..
• broadcast


# Page. 48

![Page Image](https://bcdn.docswell.com/page/4JMZW3QPEW.jpg)

4人プレイにおけるothercast
• 1個のパケットを受信したら、3つを送信する
• サーバーマシンにおける通信量は、受信1に対して送信3
B
data
A
data
room0
roomN
サーバープロセス
data
C
data
D


# Page. 49

![Page Image](https://bcdn.docswell.com/page/PJR6YQ8Y79.jpg)

4人部屋のパケット(othercast)
B
data
ACK
A
data
ACK
data
サーバープロセス
ACK
C
data
dataひとつに対してサーバは
全部で受信4,送信4で合計8個のパケットを送受信する。
RUDPの場合dataの長さは0~576バイト。
TCPは約1500バイト以下
ACKは最大22バイト
ACK
D


# Page. 50

![Page Image](https://bcdn.docswell.com/page/PEXMG5847X.jpg)

4コアマシンの典型的な構成
・・・・・・・・・
・・・・・
room0
room1
room2
・・・
sv0
roomN
・・・
roomN
sv2
roomN
sv1
サーバーマシン
roomN
sv4
roomN
sv3
sv5
1台のインスタンスに
6〜8個のサーバプロセスを置く
1個のサーバプロセスが
500〜2000の部屋をホストし、
合計で5000〜10000程度の
同時接続数に対応


# Page. 51

![Page Image](https://bcdn.docswell.com/page/3EKG46KPJD.jpg)

インスタンスは何個必要か？
•
•
1台の4コアマシンに可能な入力
• 帯域幅の限界 : 1.2Gbps〜8Gbps
• パケット数の限界 : 合計15万〜90万/sec
• 暗号 : 送受信合計で 50Mbytes/sec
上記の入力上限を超えるごとに1台必要
全部でどれだけの通信が必要かは、完全にゲーム内容による


# Page. 52

![Page Image](https://bcdn.docswell.com/page/L73NL6Z475.jpg)

ゲーム内容によるとはいえ、
最初は詳しい仕様が決まっていないもの。
大ざっぱに考えたらOK


# Page. 53

![Page Image](https://bcdn.docswell.com/page/87DWNVR5JG.jpg)

1インスタンスがホストできる同時接続数
•
適当に仮定を置く
•
メッセージサイズ:200バイトに固定。ちょっと長いけど。
•
暗号化通信のコストは無視でOK
•
送り方は othercastに固定。だいたいのゲームはこれでOK
•
通信モデルはホストーゲスト型(ホスト役以外全員がゲスト)に固定
•
部屋の参加人数によらず、ホストが1送ったらほかの全員が1受信する
•
マシンは AWSの m4 (15万packet/sec, 1.2Gbps)と仮定
•
ACKパケットは必ず発生すると仮定


# Page. 54

![Page Image](https://bcdn.docswell.com/page/VJP95VWDE8.jpg)

1インスタンスがホストできる同時接続
15万pkt/sec
1.2Gbpsでの
での限界
限界CCU
CCU
サーバへの送信
/sec/CCU
サーバからの送信
/sec/CCU
サーバでの
合計パケット数
/sec/CCU
ACKも含めた
パケ数
バイト数
ターン制ゲーム
1msg/sec
1
1
2
4
400
37500
375000
低速少量アクション
クラッシュ系、
パズルやスポーツゲームなど
5msg/sec
5
5
10
20
2k
7500
75000
高速大量アクション
MOBAやRTS,物理があるFPSな
ど
30msg/sec
30
30
60
120
12k
1250
12500
可能なCCUの小さい方を採用する。
ゲームではパケットが小さいので、
だいたいいつもパケット数の制限が帯域の制限よりきつい


# Page. 55

![Page Image](https://bcdn.docswell.com/page/2EVMPZ8GEQ.jpg)

1インスタンスがホストできる同時接続
• まとめると
• ターン制ゲームは37500CCU(同時接続)
• 低速少量アクションは 7500
• 高速大量アクションは1250
• 安全係数を0.5程度掛けると
• ターン制ゲームは 18750
• 低速少量アクションは 3750
• 高速大量アクションは625


# Page. 56

![Page Image](https://bcdn.docswell.com/page/57GGP4ZD7L.jpg)

1024以上のCCUに対応するための設定
•
•
TCPを使う場合は2つの制限が問題になりやすい
• ユーザアカウントあたりの最大ソケット数
• ローカルポート数
負荷テストを行うときは、UDPのクライアント側で
も上記の問題は起きる


# Page. 57

![Page Image](https://bcdn.docswell.com/page/4EQX2GLX7P.jpg)

ユーザアカウントあたりの最大ソケット数
•
ulimit -a で確認
このユーザでは1024個までしかソケットを作れない。
TCPでは1CCUあたり1個のソケットが必要。
UDPでもクライアントでは1CCUあたり1個必要。
ulimit -nコマンドで設定してもハードリミット以上は無理
/etc/security/limits.conf の末尾あたりに
サーバを起動するユーザーで
softとhardリミットの値を書いておくだけでOK。再起動不要


# Page. 58

![Page Image](https://bcdn.docswell.com/page/KJ46L5D271.jpg)

ローカルポート数の枯渇
•
TCPまたはUDPのソケットを作ると、localポート番号が1個割り当てられる
•
CentOSやAmazon Linuxの設定では、デフォルトで32768から60999までの28232個が使
われる。
•
28232個を超える数のソケットを作ることができない。
•
Linuxカーネルの設定を変更することもできるが、推奨しない。
•
インスタンスあたりCCUは28232よりだいぶ小さい数、
できれば10000〜15000以下で計画するのが良い。
•
そのためにxlargeではなくlargeタイプを使うのも良い案となる。


# Page. 59

![Page Image](https://bcdn.docswell.com/page/LE1VLWZK7G.jpg)

1インスタンスあたりの容量計画(最終案)
サーバでの
合計パケット数
/sec/CCU
ACKも含めた
パケ数
15万pkt/secでの
限界CCU
安全マージン0.5
インスタンスタイプ
ターン制ゲーム
1msg/sec
2
4
37500
18750
4コアマシン1台分を、
2コアマシン2台に分ける(9375CCU)
低速少量アクション
クラッシュ系、
パズルやスポーツゲームなど
5msg/sec
10
20
7500
3750
4コアマシンでOK
高速大量アクション
MOBAやRTS,物理があるFPSなど
30msg/sec
60
120
1250
625
4コアマシンでOK
これで負荷テストで確認したいだいたいの性能の目標が得られた。
あてずっぽうの負荷テストを避けられる。


# Page. 60

![Page Image](https://bcdn.docswell.com/page/GEWLV69P72.jpg)

mrs_room_benchの内容
•
•
•
配布物はサーバとクライアントの両方を含む
ビルド方法と起動方法
• 詳細は mrs_room_bench/README.md
を参照
• サーバーを起動するには ./sv とするだけ
• クライアントを起動する方法は後述
評価版の注意点
• 最大接続数が100に制限されている


# Page. 61

![Page Image](https://bcdn.docswell.com/page/47ZM4Y96E3.jpg)

mrs_room_bench 1:1構成
user0
room0
user1
room1
user2
…
user3
user4
user5
svプロセス
clプロセス
…
roomN
userN
svプロセスにたいして
clプロセスが多数のユーザーのかわりとなって負荷をかける
ルームあたりのユーザー数は設定できる
svもclも複数化できる


# Page. 62

![Page Image](https://bcdn.docswell.com/page/YJ6N3DKLJV.jpg)

mrs_room_bench 1:n構成
room0
user0
user1
room1
sv
room2
user2
user3
cl0
user4
user5
user6
user7
cl1
…
サーバーよりクライアントのほうが処理負荷が高くなるので、
svプロセスの最大性能が知りたい場合は、
1個に対してクライアント複数から負荷をかける必要がある


# Page. 63

![Page Image](https://bcdn.docswell.com/page/GJ55L3PMJ4.jpg)

mrs_room_bench n:n構成
room0
user0
user1
room1
sv0
user2
room2
user3
room3
user4
cl0
user5
room4
sv1
room5
user6
user7
cl1
…
…
MRSはシングルスレッド実装なので、
マルチコアマシンの総合性能を知りたい場合は、
svプロセス自体を増やす必要がある


# Page. 64

![Page Image](https://bcdn.docswell.com/page/9E2NLZ6R7R.jpg)

mrs_room_benchの起動
•
•
•
•
•
•
•
•
•
レポジトリのmany.shを修正して起動する
ADDR : 接続先サーバーのIPアドレス
PROTO : 使用プロトコル。 TCP, UDP, WS, WSSのいずれか
N : 同時接続数。4の倍数がのぞましい(部屋あたり4人なので)
SIZE : メッセージサイズ。1以上64K以下、通常は32や200、大きい場合は5000〜10K以内で試す
ENC : 暗号化するかどうか。1なら有効、0なら無効
INTERVAL : メッセージ送信間隔ミリ秒
UNRELIABLE : UDPの場合これを1にすると信頼性なしモードで送信
CREATEINTERVAL : ユーザーを新規作成する頻度。100ミリ秒を指定すると100ミリ秒ごとに新規接続をする


# Page. 65

![Page Image](https://bcdn.docswell.com/page/D7YPQR957M.jpg)

mrs_room_benchの出力凡例
ここまで、毎秒10本づつCCUを増加させている
ここから、負荷が安定している
現在時刻
unixtime
•
•
pid
ループ回数
クライアント数
(CCU)
送信間隔
送ったバイト数
受信バイト数(MiB)
manysv.sh では複数のサーバーをポート番号を変えながら同時に起動できる。
他にもオプションはたくさんあるので、 mrs_room_bench/README.mdを参照して下さい。


# Page. 66

![Page Image](https://bcdn.docswell.com/page/VEN5KDL4J8.jpg)

mrs_room_benchのよくあるエラー
•
サーバーでのJOIN_ROOM_ERROR連発
mrs_room_benchのcliプログラムをctrl-cで止めてから、
30秒たたないと部屋が削除されないので再び作ることができないことが原因。
mrs_roomサーバーを再起動するか30秒待ってクリアされるかどちらかが必要。
「エラーで困ったらsv再起動」


