Amazon EC2 の C5n インスタンスで 100 Gbps にチャレンジしたとき1 に、TCPで実効 80 Gbps位しか出なかったことを記事にしましたが、それを読んだ方からいろいろアドバイスをいただいて試してみたところ、何とか 約 100 Gbps を達成できたのでご報告します。
Placement Group
Amazon Web Service (AWS) の機能に Placement Group という機能があります。これを使ったほうがいいのでは? というコメントをいただきました。
Placement Group というのは、EC2 インスタンスを論理的にグループ化して、通常の VPC Subnet に配置した場合よりも低レイテンシでのネットワークを提供するものです。
TCP での通信では、ACK での到着確認待ちが発生するためネットワークのレイテンシが高いと、実効通信速度が遅くなるという特性があります。そのためレイテンシが低いのは実行速度を稼ぐうえで有利になります。
また前回一つのエンドポイントあたり 25 Gbps の制限があるようだということを書きましたが、 Placement Group の内 Cluster Placement Group では、マニュアルによると以下のように制限が緩和されています。
- シングルフロートラフィック 10 Gbps
- Amazon S3 バケットと同一リージョン内のインスタンス間ではインスタンスで利用可能なトラフィックすべて
ということは、前回のように ENA を追加しなくても、100 Gbps まで行きそうです。実際に試してみたところ。シングルフロートラフィックで、9.5 Gbps 位、1プロセス 8 多重で大体 28 Gbps を達成できました。
iperf3 ではマルチスレッドやマルチプロセスを使用せずに、1 プロセスでソケットを多重化しています。そのため、全て単一コアで処理されるため、CPUの処理能力がボトルネックになり、パケット生成や受信処理が追い付かなくなるケースがあります。今回の結果を見ると単一プロセスで単純にソケットを多重化しただけだと、おおよそ 30 Gbps あたりが性能限界となるようです。
CPU処理がボトルネックになることは INTEL でも認識されていて、後述の RSS のような技術や、DPDK2 のようなプロジェクトもあります。
そこで、iperf3 を複数起動して合計値を測定してみました。1 プロセスあたり 8 多重、4プロセスで測定したところ合計でおおよそ 80 Gbps 程度を達成することができました。
がやはり 80 Gbps 程度しか実現できませんでした。
NUMA, CPU Affinity と RSS
NUMA やキャッシュを意識してみてはどうか?というご意見もありました。NUMA とは、CPUソケットごとに接続するメモリを分割してメモリアクセスを多重化しようという機構です。
RSS は、NICからの割り込み複数のCPUコアに分散させることで、割り込み受信処理に従うCPUの負荷を分散させる仕組みです。
iperf3 では "-A" オプションで実行する CPU 番号を指定することができます。今回は、ソケット0 番側、かつ RSS で割り込みが当たっている CPU を /proc/interrupt から拾って、"-A" オプションで指定しました。全部で 16 程割り込みが当たっていたので、それぞれ iperf3 のプロセスを割り当ててみました。
これで、85 Gbps 程度達成できました。 なかなか 90 Gbps を超えてくれません。
ペーシング
じっと iperf3 の出力をじっと観察していると、どうも受信側の取りこぼしが多いように見えました。
どのみち、複数プロセスに分割しているのと CPU の負荷が問題であるならば、1プロセスあたりの送信量を制限しても問題はなさそうです。
iperf3 では "--fq-rate" オプションで、ソケット当たり 800M 程度に制限してみました。
でこれで 95 Gbps 程度を達成することができました。これぐらいならば種々のオーバーヘッドを考慮してほぼ満足できる結果だと思います。
ペーシングに関してはこちら3 でも推奨事項として挙げられています。
最後に
他にもいろいろ検討事項はあったのですが、それはまた別の機会に。