LoginSignup
54
37

More than 3 years have passed since last update.

実効速度 Over 20G 高速ネットワークを予算1.5万円で作る

Last updated at Posted at 2019-12-03

この記事は Jsys Advent Calendar 2019 の4日目の記事です.
昨日は @epsilonoom による Nintendo Switchでコーディングしよう! でした.ゲーム機でゲームを作るのはメタ的で面白いですね.個人的には「Baba Is You」や「ヒューマンリソースマシーン」などのプログラマ向けパズルゲームもおすすめです.
明日は undefined による undefined です.

この記事は Coins Advent Calendar 2019 の4日目の記事です.
昨日は突撃隊による 自作OSでマルチタスクやったでした.以前から自作OSを作っているのは知っていましたがついにマルチタスクまで進んだようです.動作報告が楽しみです.
明日はてっつーによる「ぼくの母恵夢」です.

この記事は WORDIAN Advent Calendar 2019 の4日目の記事です.
昨日は突撃隊による 自作OSでマルチタスクやったでした.(ry
明日は segmentation fault 11(core dumped)

ところで

皆さんの家のネットワークはどのくらいの速度が出ますか? 我が家は2Gbpsでます.1

しかしそれはWAN,つまり外部との通信の話.デスクトップやサーバーはそれぞれGbEのポートしか無いので 1Gbpsしか出ません.
インターネット(WAN)に通信するときは相手方がボトルネックになることが多いので実効1Gbpsも出れば十分です2.実際今までこの回線で不満だったことは私はありません.3

しかしLANとなると話は別です.1Gbpsというと十分速いように聞こえますが bps は bits per seconds,…つまり Byte に直すと 125MB/s になります.1Gbpsだと秒間1GBくらい通信してる感じがしてくる気がしますが実際は秒間125MBしか転送できないのです.表で比較してみるとこんな感じです.

媒体 速度(目安)
GbE 125MB/s
HDD 160MB/s
SSD(SATA) 500MB/s
10GbE 1250MB/s
SSD(NVMe) 4000MB/s

なんと GbE は HDD よりも遅い.
このHDDの記録は自宅にあった WD Blue 5400RPM を適当に Crystal Disk Mark で計測したものです.特にハイエンドHDDというわけではありませんがHDDよりもGbEの方が遅いのです.
更に業務PCや逸般の誤家庭などで,HDDやSSD数枚でRAIDで組んだり,NASだけどNVMe SSDで構成しているような場合は 10GbE でもネットワークがボトルネックになります.

例えば映像クリエイターで動画素材をサーバーに置いた状態でレンダリングをするレンダークラスタをお持ちの方や,サーバーいじりや機械学習などで大量のデータが入ったVHDをNASに置いて運用しているなどの状況ではモロにこのGbEがボトルネックになります.

我が家の場合はサーバーに置いた動画データやVHDのコピーや,デスクトップPCのバックアップをサーバーに転送しているときなどに,ネットワークがサチっていました.

うちのサーバーのメインストレージは WD Red 7200RPM なのでそこまで高速なネットワークで組む必要はなかったのですが,予算 1.5 万円で,実効速度 20Gbps 超えのローカルネットワーク が作れることが判明したので作っちゃった話です.

これは実際今回作ったネットワークの様子です.
Title

InfiniBand

InfiniBand って知っていますか? 私は知っています.4

詳しく気になった方は WikipediaQiitaArchWikiこの辺の記事 などを読んでほしいのですが,簡単に言うと HPC5向けの高速ネットワーク規格です.

ネットワークを組む際は Ethernet を使うことが一般的だと思いますが,古典的なEthernetは意外と無駄が多く,規格として高性能化するのが難しい問題があります.そんなEthernetを克服すべく規格されたのがInfiniBandです.

IBの主な特徴としては,

高スループット

IB にもいくつかのバージョンがあるのですが,最新のHDR規格であれば4レーン接続で200Gbpsの超高スループットが出ます.

低レイテンシ

Ethernetでは通信する際にMACアドレスを使用します.しかしMACアドレスは48bitもの長さがあるので,スイッチングハブがパケットを転送する際,MACアドレスとポートの対応にはハッシュテーブルのような複雑なデータ構造が必要になります.
IB も GUID という製造時に振られる識別子がありますが,通信の際にはトポロジー内でユニークな 16bitのLID を用いて通信します.このうち ユニキャスト LID は 49,151 個しかないので,各1バイトずつポート情報を持っても 48 KB 程度と,スイッチのCPUキャッシュに配列をそのまま載せることができるので低レイテンシで通信できます.

トポロジーにLIDを振るにはサブネットマネージャ(SM)を立てます.これはSM起点で各ポートをスキャンしていき,どこにどの機器が接続されているかを検出し,ファブリック(IBのトポロジーのこと)を随時認識します.ファブリック内にSMは1つあれば良く,InfiniBandインテリジェントスイッチと呼ばれるスイッチではスイッチにSMが内蔵されています.インテリジェントスイッチが無くても,OpenSM という OSS 実装があるので使用時に常に起動しているサーバーがあればそれにインストールすれば問題ないです.

Remote Data Memory Access (RDMA)

通常のアプリケーションは通信時に,メモリに載ったアプリのデータをOSのデータバッファにコピーして転送する等,メモリ→OS→相手OS→相手メモリ と沢山のメモリコピーが発生しますが,RDMAではリモートコンピュータのメモリアドレスを指定してデータを読み書きすることができます.つまりとてもはやい.

IP over IB(IPoIB)

IB は OSI 参照モデルで言うデータ層(第2層)からトランスポート層(第4層)まで一括で提供しています.しかしHPC用途以外で使うときは,IP(第3層)やTCP/UDP(第4層)も使いたいところです.
IBではIB上にIPプロトコルを流す IPoIB を使用することができます.本来のIBの速度よりは効率が落ちてしまいますが,実家のような安心感で ping を飛ばしたり,TCP/IP 通信できます.

他にもすごい機能がいっぱい!

他にも強いフロー制御やゼロコピー,ループが存在するトポロジーも許すなど様々な機能があります.ここでは書かないので気になった方は調べてみてください.

いかがでしょうかInfiniBand.ちょっと認識が怪しい部分もあるので通りすがりのプロで間違いに気づいた方は指摘してください.

でもお高いんでしょ…

新品で HCA(Host Channel Adapter, いわゆるNIC)を買った場合,最新のHDRで200Gbpsが出る Mellanox ConnectX-6 の場合,1ポート製品(MCX653105A-HDAT)で184,580円,2ポート製品(MCX653106A-HDAT)で276,760円で買えるようです.(税込,2019年12月4日現在)
ConnectX の場合,IBモードの他にEthernetモードでも動作可能なので,IBに不慣れな方でも導入敷居は低めですが,大学生の趣味などではちょっと手が届きにくいですね.(もっともコレは最上位機種なので,より安い機種もありますが)

そこでIBの見どころとして, 手頃な中古品が ebay などの市場で安価に出回っている というポイントがあります.ArchWiki でも

巨大企業が新しいバージョンを求めることなどから InifiniBand の中古市場は飽和状態となっており、家庭や小規模オフィスの内部ネットワーク用として中古の InfiniBand デバイスが手軽な価格で入手することができます。

と紹介されています.
例えば FDR x4に対応していて 54.55Gbps出る2ポートHCA MCX354A-FCBT は1枚5000円程度から,1ポートHCAのMCX353A-FCBTも同様の価格で出品されています.
似た型番に MCX353A-QCBT, MCX354A-QCBT というものもありますが,これらは FDRより1つ遅い QDRx4(40Gbps)であり,Ethernetは10Gbpsまで対応の製品です.
これらはConnect-X 3シリーズというものなのですが,Connect-X 2以下のシリーズでは Windows 7 までの対応なので,最近のWindowsでも使いたい場合は注意が必要です.

今回は, MCX354A-FCBT を2枚と MC2207130 という FDR 対応のケーブル1本を注文し,送料込みで14,984円かかりました.リーズナブルでしょ?

※今回は小規模ネットワークなのでIBスイッチは購入しませんでした.2ポートHCAなのでいざというときはデイジーチェーンさせれば良いのと,IBスイッチはファンの騒音が結構激しいので,寝室と同じ部屋に設置すると寝れなくなります.

構築編

購入したHCAは以下のマシンに取り付けました.

クライアント
CPU : Intel Core i9-7900X
RAM : DDR4 3200MHz 64GB
OS  : Windows 10 1903
サーバー
CPU : Intel Core i3-6100
RAM : DDR3 2133MHz 16GB
OS  : Windows Server 2012R2

そのまま指しただけでも,Windows標準ドライバで動作させることができます.
Windowsからは56GbpsのNICとして見えているようです.
NetworkAdapterProperties.png
※設定を済ませたあとのスクショなので,何バイトか通信されてるように出てます.

しかしこのままだとIB関係のツールが使えないので,この記事を参考にしつつ,ドライバーをダウンロード・インストールします.Connect-X 3 の場合は WinOF ドライバを使います.現時点での最新は 5.50.52000 でした.ドライバと一緒にHCAのFWアップデートもされるのでしましょう.

Windows Server 2012 R2にインストールしようとしたら「mofcompが見つかりません」と怒られました.調べたらC:\Windows\System32\wbem\にあったのでパスを通したらうまく行きました.

ドライバインストールすると, C:\Program Files\Mellanox\MLNX_VPI\IB\Tools 以下に様々なツールがインストールされます.ひとまず ibstat で IB の状態を確認してみます.

Server
C:\Program Files\Mellanox\MLNX_VPI\IB\Tools>ibstat
CA 'ibv_device0'
        CA type:
        Number of ports: 2
        Firmware version: 2.42.5000
        Hardware version: 0x0
        Node GUID: 0x0002c90300a4c080
        System image GUID: 0x0002c90300a4c083
    Port 1:
        State: Initializing
        Physical state: LinkUp
        Rate: 56
        Base lid: 0
        LMC: 0
        SM lid: 0
        Capability mask: 0x90580000
        Port GUID: 0x0002c90300a4c081
        Link layer: IB
        Transport: IB
    Port 2:
        State: Down
        Physical state: Polling
        Rate: 40
        Base lid: 0
        LMC: 0
        SM lid: 0
        Capability mask: 0x90580000
        Port GUID: 0x0002c90300a4c082
        Link layer: IB
        Transport: IB
Client
C:\Program Files\Mellanox\MLNX_VPI\IB\Tools>ibstat
CA 'ibv_device0'
        CA type:
        Number of ports: 2
        Firmware version: 2.42.5000
        Hardware version: 0x0
        Node GUID: 0x0002c90300a4bed0
        System image GUID: 0x0002c90300a4bed3
    Port 1:
        State: Initializing
        Physical state: LinkUp
        Rate: 56
        Base lid: 0
        LMC: 0
        SM lid: 0
        Capability mask: 0x90580000
        Port GUID: 0x0002c90300a4bed1
        Link layer: IB
        Transport: IB
    Port 2:
        State: Down
        Physical state: Polling
        Rate: 40
        Base lid: 0
        LMC: 0
        SM lid: 0
        Capability mask: 0x90580000
        Port GUID: 0x0002c90300a4bed2
        Link layer: IB
        Transport: IB

どちらも Port 1 にのみ接続したので,Port 1 が LinkUp/Initializing になりました.
逆に Port 2 には接続していないので,Polling / Down になっています.

現在,直挿しでどこにもサブネットマネージャーが居ないので,State: Initializing になっています.

Server
sc create OpenSM binPath= "c:\Program Files\Mellanox\MLNX_VPI\IB\Tools\opensm.exe --service" start=auto

をして Windows Server 側でサービス化しておきます.

これで Server が起動している間は,IB ネットワークが使えるようになります. ibstat で Port 1 を確認してみると

Server
Port 1:
        State: Active
        Physical state: LinkUp
        Rate: 56
        Base lid: 1
        LMC: 0
        SM lid: 1
        Capability mask: 0x90580000
        Port GUID: 0x0002c90300a4c081
        Link layer: IB
        Transport: IB
Client
    Port 1:
        State: Active
        Physical state: LinkUp
        Rate: 56
        Base lid: 2
        LMC: 0
        SM lid: 1
        Capability mask: 0x90580000
        Port GUID: 0x0002c90300a4bed1
        Link layer: IB
        Transport: IB

と両方 Active になりました!

OpenSMはデフォルトでHCAの1番ポートから順にファブリックを認識していきます.
HCAに2本ケーブルを指し,1番ポートと2番ポートが別のサブネットに居る場合は2番に永遠にLIDが振られず通信ができません.

Server
c:\Program Files\Mellanox\MLNX_VPI\IB\Tools\opensm.exe --service -g 0x0002c90300a4c082

のように,-gで2番のGUIDを指定指定してあげることで,2番ポートからのファブリックの調査がされます.僕は過去に2番ポートに挿しているにも関わらず-g無しでOpenSMを立ち上げてて通信できない問題に直面して2週間ぐらい悩んでました.

疎通テスト

待機側で ibping -S コマンドを実行すると ibping の待機が開始されます.
とりあえず Server/Cliant 両方で待機させて,お互いに疎通できてるか試します.

Client
C:\Program Files\Mellanox\MLNX_VPI\IB\Tools>ibping 1
Pong from ?hostname?.?domainname? (Lid 1): time 0.296 ms
Pong from ?hostname?.?domainname? (Lid 1): time 0.374 ms
Pong from ?hostname?.?domainname? (Lid 1): time 0.625 ms
Pong from ?hostname?.?domainname? (Lid 1): time 0.529 ms

--- ?hostname?.?domainname? (Lid 1) ibping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3130 ms
rtt min/avg/max = 0.296/0.456/0.625 ms

C:\Program Files\Mellanox\MLNX_VPI\IB\Tools>ibping 2
Pong from ?hostname?.?domainname? (Lid 2): time 0.239 ms
Pong from ?hostname?.?domainname? (Lid 2): time 0.437 ms
Pong from ?hostname?.?domainname? (Lid 2): time 0.464 ms
Pong from ?hostname?.?domainname? (Lid 2): time 0.412 ms

--- ?hostname?.?domainname? (Lid 2) ibping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3705 ms
rtt min/avg/max = 0.239/0.388/0.464 ms

IB では Macアドレスの代わりに lid で通信します.ibstat の Base lid: と書かれていたところがそうです.
なので ibping 1 でサーバーへの ping,ibping 2 でクライアント(自分自身)への ping となります.

IPoIB

HCAにIPアドレスを振ることでIPによる通信ができます.コントロールパネルのネットワーク接続から Mellanox ConnectX-3 IPoIB Adapter を探し,いつものように固定IPとサブネットマスクを振ります.デフォルトゲートウェイ等は必要ありません.とりあえず

NIC IB-HCA
Server 192.168.1.2 192.168.222.2
Client 192.168.1.4 192.168.222.4

と振りました.(NICは普段使っているEtherのIP)
お互いに ping を飛ばして疎通しているか試します. ibping と違いサーバー側で待機する必要はありません(それはそう,実家のような安心感).

IPによる通信ができたので,iperf3 で速度テストします.5201番ポートを開放してチェックします.まずは GbE から

Server
iperf3.exe -s
Client
>iperf3 -c 192.168.1.2
Connecting to host 192.168.1.2, port 5201
[  4] local 192.168.1.4 port 1395 connected to 192.168.1.2 port 5201
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec   108 MBytes   905 Mbits/sec
[  4]   1.00-2.00   sec   112 MBytes   938 Mbits/sec
[  4]   2.00-3.00   sec   113 MBytes   948 Mbits/sec
[  4]   3.00-4.00   sec   113 MBytes   948 Mbits/sec
[  4]   4.00-5.00   sec   113 MBytes   949 Mbits/sec
[  4]   5.00-6.00   sec   113 MBytes   949 Mbits/sec
[  4]   6.00-7.00   sec   113 MBytes   948 Mbits/sec
[  4]   7.00-8.00   sec   112 MBytes   940 Mbits/sec
[  4]   8.00-9.00   sec   113 MBytes   945 Mbits/sec
[  4]   9.00-10.00  sec   113 MBytes   949 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec  1.10 GBytes   942 Mbits/sec                  sender
[  4]   0.00-10.00  sec  1.10 GBytes   942 Mbits/sec                  receiver

iperf Done.

通常の GbEですね.次は IPoIB

>iperf3 -c 192.168.222.2
Connecting to host 192.168.222.2, port 5201
[  4] local 192.168.222.4 port 1397 connected to 192.168.222.2 port 5201
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-1.00   sec   411 MBytes  3.45 Gbits/sec
[  4]   1.00-2.00   sec   444 MBytes  3.73 Gbits/sec
[  4]   2.00-3.00   sec   457 MBytes  3.83 Gbits/sec
[  4]   3.00-4.00   sec   466 MBytes  3.91 Gbits/sec
[  4]   4.00-5.00   sec   429 MBytes  3.60 Gbits/sec
[  4]   5.00-6.00   sec   410 MBytes  3.44 Gbits/sec
[  4]   6.00-7.00   sec   451 MBytes  3.78 Gbits/sec
[  4]   7.00-8.00   sec   450 MBytes  3.78 Gbits/sec
[  4]   8.00-9.00   sec   455 MBytes  3.82 Gbits/sec
[  4]   9.00-10.00  sec   469 MBytes  3.94 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bandwidth
[  4]   0.00-10.00  sec  4.34 GBytes  3.73 Gbits/sec                  sender
[  4]   0.00-10.00  sec  4.34 GBytes  3.73 Gbits/sec                  receiver

iperf Done.

GbE よりは速いですけど,なんかパッとしませんね.それもそのはずで,IBは複数スレッド張らないとその真価は発揮できません.もう一度試してみます.

>iperf3 -c 192.168.1.2 -P 4
~省略~
[SUM]   0.00-10.00  sec  1.09 GBytes   934 Mbits/sec                  sender
[SUM]   0.00-10.00  sec  1.09 GBytes   934 Mbits/sec                  receiver

GbEではやはり 1Gbps 程度止まりだったものが

>iperf3 -c 192.168.222.2 -P 4
[SUM]   0.00-10.00  sec  8.10 GBytes  6.96 Gbits/sec                  sender
[SUM]   0.00-10.00  sec  8.10 GBytes  6.96 Gbits/sec                  receiver
>iperf3 -c 192.168.222.2 -P 6
[SUM]   0.00-10.00  sec  17.7 GBytes  15.2 Gbits/sec                  sender
[SUM]   0.00-10.00  sec  17.7 GBytes  15.2 Gbits/sec                  receiver
>iperf3 -c 192.168.222.2 -P 8
[SUM]   0.00-10.00  sec  19.0 GBytes  16.3 Gbits/sec                  sender
[SUM]   0.00-10.00  sec  19.0 GBytes  16.3 Gbits/sec                  receiver
>iperf3 -c 192.168.222.2 -P 10
[SUM]   0.00-10.00  sec  15.4 GBytes  13.2 Gbits/sec                  sender
[SUM]   0.00-10.00  sec  15.4 GBytes  13.2 Gbits/sec                  receiver
>iperf3 -c 192.168.222.2 -P 12
[SUM]   0.00-10.00  sec  14.7 GBytes  12.6 Gbits/sec                  sender
[SUM]   0.00-10.00  sec  14.7 GBytes  12.6 Gbits/sec                  receiver

と,並列数を上げることによって 16Gbps ぐらいで通信できました!

SMB over RDMA

ファイルサーバーのボトルネック解消を目的とするならば,いちばん重要なポイントです.Windowsによるファイル共有はSMBを使って行うことができますが,RDMA を使ってファイル転送することができます.
設定は https://www.slideshare.net/detteiu/infiniband-hackathon-2-windows を参考にします.
と言ってもチェックすべき項目は全て既にOKだったので Explorer から相手に接続すればそれで完了でした.
IP直打ちやらメトリック変更やらルートを教えなくても,OSからは 56Gbps NIC として認識されているのでホスト名打てば勝手に IB を使ってくれました.

以下,検証です.ストレージは各マシンにRAMディスクを作って,RAMディスク同士でファイルコピーをしました.
RAMディスク自体の速度は以下のとおりです.

サーバーのRAMディスク

server_storage.png

クライアントのRAMディスク

client_storage.png

雫ちゃん可愛い!!

この状態で,CrystalDiskMark のフォルダー選択で,ネットワークドライブのフォルダを指定して,ベンチマークを行います.
結果は以下の通りです.

クライアントからサーバーのフォルダをベンチマーク

client_toServer.png

シーケンシャルReadに関して,2201 MB/s = 17.6 Gbps の速度を達成しました.これは10GbEでも達成することはできず,高速な NVMe SSD ストレージにネットワーク越しでアクセスする場合でもニッコリの速度です.
しかしWriteに関しては375 MB/s = 3.0 Gbps と少し速度が出ていません.

今度は逆にサーバー側からクライアントのストレージを触ってみました.

サーバーからクライアントのフォルダをベンチマーク

server_toClient.png
シーケンシャルWriteに関して,2301MB/s = 18.4 Gbps を達成していますが,Read は 718 MB/s = 5.7 Gbps でサチっています.
クライアントからサーバーのフォルダを触ったときよりは出てますが,それでも Client→Server方向のデータ送信が速度が出ていません.

気になったので今度は,サーバー側からクライアントのファイルをクライアントのフォルダーへコピーしました.

クライアントからサーバーのファイルをサーバーのフォルダーへコピー

server_cliant_copy.png
このベンチマークでは,双方向 4.5 Gbps = 562 MB/s 出ました.クライアントからサーバーのWriteをしているのにも関わらず,CrystalDiskMark よりも速度が出ているのはよく分かりません.

最後に逆にサーバーから操作した場合です.

サーバーからクライアントのファイルをクライアントのフォルダーへコピー

cliant_server_copy.png

こちらは 8.1Gbps = 1012 MB/s 出ました.サーバーからクライアントのファイルを操作することはあまり無いとは思いますがこの速度が出るなら,別のPCから別のPCのファイルを読み書きする場合でも,ネットワークがボトルネックになる環境は少なさそうです.
やはり CrystalDiskMark と別の傾向が出たのは理由は分かりません.

RDMA では相手のメモリを直接触れるという認識なのですが,RAMディスクでベンチマークをしている関係上,メモリ同士の処理になるのであまり良くないことが発生しているのかもしれません.
クライアント側はともかくサーバーには M.2 SSD スロットが無く高速な実ストレージ環境が今回は用意できなかったので,RAMディスクでは無い場合の調査はできませんでした.

まとめ

意外とGbEは遅いということで,今回は実効 20Gbps 以上出る高速なネットワークを予算1.5万円で作った話を紹介しました.
一応規格上は54Gbps出るはずなのですが,オーバーヘッドなどもあるのでひとまず良しとしましょう.

SMB over RDMA では一部の結果では IB にしては遅い所もありましたが,最低でも 3 Gbps 以上は出ていたので我が家の環境では問題無いのでひとまずこのまま運用したいと思います.

この構成にしてしばらくしたらクライアントPCのバックアップが始まりサーバーのNASにコピーが始まったのですが,ピークは 4 Gbps 程度まで使ってくれていたので満足です.USB-LAN2500R という 2.5G USB NIC も検討したのですが,これとほぼ同コストながら2.5G以上のネットワークが組めて本当に良かった(PCIeでは無くUSBなので持ち運びができるメリットはあるのですが,爆熱になって性能が落ちるレビューもあったので見送りました).

というわけで,自宅・職場の GbE じゃ満足できないなと感じた方はぜひ IB ネットワーク構築をしてみてはいかがでしょうか?
この記事を読んで Good と感じたらぜひ「いいね」やTweetをお願いいたします.
それでは!


  1. なお ONU には1GbEのポートしか無く,チーミングにも対応していません.悲しい. 

  2. 大学のラボとの通信は相互 900Mbps で通信でき,普段使ってるネットワークで唯一通信速度がサチる相手です.SINETつおい… 

  3. お家サーバーで不特定多数向けのサービスを展開してるような方だと不足かもしれませんが. 

  4. 何でもは知らないわよ.知ってることだけ. 

  5. High Performance Computing. スーパーコンピューターとか扱ってる分野(雑) 

54
37
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
37