多人数リアルタイム通信ボトルネック問題、扇問題について


時間がない場合は以下の三行だけ読めば大体OKです。

<font color="SlateGray">**〜〜〜〜〜〜〜 時間がない人向けに三行で説明する扇問題 〜〜〜〜〜〜〜**</font>

<font color="SlateGray">100人参加のリアルタイムマルチプレイのシューターゲームを作ろう。</font>
<font color="SlateGray">仮に1人あたりの通信量が1Mbpsくらいなら最大で100倍の100Mbpsくらい帯域あれば足りるよね。わーい。</font>

<font color="SlateGray">**→ 足りません。最大9900倍の9.9Gbps必要です。＋厄介なチューニングいっぱい。</font>**

<font color="SlateGray">**〜〜〜〜〜〜〜〜〜〜〜〜〜〜 三行説明 終 〜〜〜〜〜〜〜〜〜〜〜〜〜〜**</font>

<font color="DarkGray">*そもそも1ユーザー1Mbpsも使うのかとか、10Gbpsのインターネット接続環境を各ユーザーが持っているとは考えにくいのでその時点で不可能な要件なのですが、わかりやすくするために出した極端な例ということで・・*</font>

# 1.この投稿について
多人数リアルタイム通信に取り組む際、
特有のボトルネック問題、扇問題に悩まされます。

技術書典5で配布した”エンジニアの一生”にて
この扇問題について書いたのですが
いまいち何が問題なのかを伝えられなかったという反省がありまして
問題の解決手法というよりは、
問題そのものの理解を深めるためのまとめを書いてみました。
解決方法についてはかなり多岐にわたるので
入口の部分だけを大まかに書いています。

# 2. 扇問題のメカニズム
 
送信量が9900倍となる扇問題の発生の流れを説明します。
以下のようなシンプルなケースで考えてみましょう。

>前提：
>リアルタイム通信で各ユーザー同士の情報を常に同期するサーバーがある。
>サーバーには100ユーザーが入室している。

##1ユーザーあたりの通信同期の流れを考える
　　1. リアルタイムサーバは ユーザーC1の情報を受信
　　2. リアルタイムサーバは 99ユーザーへ送信 

**→ この場合 送信量は99倍 になります。**
![fanout-issue_image_qiita20181025_1.png](https://qiita-image-store.s3.amazonaws.com/0/64714/9dd3c0d9-46c4-a53f-27ca-7607d0581fc0.png)

##100ユーザーの通信同期の流れを考える
　　1. リアルタイムサーバは 100ユーザーの情報を受信
　　2. リアルタイムサーバは 100ユーザーそれぞれの情報受信ごとに99ユーザーへ送信

**→ この場合 送信量は9900倍 になります。**
![fanout-issue_image_qiita20181025_2.png](https://qiita-image-store.s3.amazonaws.com/0/64714/04b66d09-0c19-b99c-1933-5d833866bd4b.png)

##送信量倍率でおきるボトルネック問題 = 扇問題
このような多人数リアルタイム通信の送信量倍率によっておきるボトルネック問題を **扇問題** と私は呼んでいます。
![fanout-issue_image_qiita20181025_3.png](https://qiita-image-store.s3.amazonaws.com/0/64714/504532e5-ca9f-6435-f8c2-79047a202614.png)
この扇問題によっておきる負荷により、
ネットワークの性能限界を超えパケットドロップや切断が頻発するのです。
扇問題自体は言い回しは違えどかなり昔から存在する問題のはずなのですが、
あまり情報が共有されていないので仕事で関わると結構苦労します。
（自分は端から地雷を踏みぬいていったクチです・・・）
マルチプレイを行うリレーサーバーなどで10人あたりくらいから
動作の遅延や切断が頻発するのは根本的にはここに由来することが多いです。

#3. 何が問題なのか

## コスト
この問題が最終的に行き着くところはコストです。
調達するインフラ費用だけでなく
ボトルネック解消のチューニング工数も要しますし
倍率が高くなるほどチューニングの難易度も上がります。

- 10人同時接続なら送信量は90倍
- 100人同時接続なら送信量は9900倍
- 200人同時接続なら送信量は39800倍

同時接続数はノリで気軽に増やせるものではない
ということは頭の片隅に置いておいてもらったほうがいいかもしれません。

送信量の倍率については以下の式で求められます。

```
送信量倍率 = 同時接続数 x (同時接続数 - 1)
```
#4. 解決方法

### 各レイヤでの個別ボトルネック解消
現時点で簡単な解決方法はありません。
基本は以下に存在するボトルネックをひとつずつ解消していき
チューニングを行なっていくしかありません。

   * アプリケーション実装
   * OS/MWパラメータ
   * ネットワーク

扇問題が絡む話で有名な解決事例は大抵の場合
アプリケーション実装で空間分割やデータの送信量をカリングするなどですが
この辺りのノウハウももちろん変わらず有効な手段です。
今後もずっと使い続ける技術として残り続けることと思います。
しかし近年、要求される要件レベルが高くなってきていることもあり
ある程度はパワーで乗り切れる帯域の十分な確保という意味では、
インフラ費用とチューニング費用もそれなりにかけておいたほうが無難かもしれません。

扇問題の調査用にfoperfというのを作っています。
http://github.com/kyadet/foperf
仕事でサクッと作った程度のものなのであまり丁寧には作り込んでいませんが
どのように負荷をかけていき調査していくのか、なにかしら参考になれば幸いです。


### 広域イーサネットを使う
扇問題を解決するのではなく、扇問題のない環境を選択するという考えもあります。
たとえば広域イーサが使えるならマルチキャストで全て解決してしまうというのも手です。
そもそもローカルエリアネットワークならマルチキャスト通信が使えるので
一回の通信で複数の宛先に一括でデータ送信できてしまいますし・・・
そういう意味では扇問題はインターネットを介する通信特有の問題とも言えます。



### 時間が解決してくれるのを気長に待つ
急いでない場合はクラウド基盤やOS/MWなどの
バージョンアップによって解決するのを気長に待つという考えもあります。

そもそもインターネットという仕組み自体はN:N型通信、N:M型通信を前提として考えられており
扇問題のようなものを"問題"として呼ぶ機会があること自体おかしな話ではあるのです。
これには背景あり、各レイヤのボトルネック解消に取り組んでいくと見えてくるのですが
長い間多くのプロダクトがクライアント・サーバー型の1:1通信のやり取りを中心に行ってきたせいか、
多くの既存のプロダクトが1:1通信を前提に作られてしまっており、
N:N型通信を行う際に裏目になるような作りになってしまっているものが多いのです。
つまり、扇問題が問題視されるようになれば
今後は各プロダクトが個別にバージョンアップとともに最適化していくものと思われますので
待っていればいずれ解決していくとは思います。
<br>
<br>
<br>
<br>
今回は具体的なボトルネック解消方法については書きませんでしたが
また機会と時間があればマルチパスネットワーキングによるボトルネック解消の話とか書いてみようと思います。