私のサーバーが新しい着信TCP接続をaccept()できるレートは、Xenでは本当に悪いです。ベアメタルハードウェアでの同じテストは、3〜5倍のスピードアップを示しています。
最近、Xenで実行されている自社開発のJavaサーバーのパフォーマンスのボトルネックを調査しています。サーバーはHTTPを話し、単純なTCP接続/要求/応答/切断呼び出しに応答します。
ただし、サーバーに大量のトラフィックを送信している間でも、1秒あたり7000を超えるTCP接続を受け入れることはできません(8コアEC2インスタンス、Xenを実行するc1.xlarge)。テスト中、サーバーは奇妙な動作を示し、1つのコア(cpu 0とは限らない)の負荷が> 80%を超え、他のコアはほとんどアイドルのままです。これにより、問題はカーネル/基盤となる仮想化に関連していると思います。
同じシナリオをベアメタルの非仮想化プラットフォームでテストすると、TCP accept()レートが35 000 /秒を超えるというテスト結果が表示されます。これは、Ubuntuを実行するCore i5 4コアマシン上で、すべてのコアがほぼ完全に飽和しています。私には、そのような図が正しいと思われます。
Xenインスタンスでも、sysctl.confにあるほとんどすべての設定をenable/Tweakで試しました。 Receive Packet Steering および Receive Flow Steering の有効化とスレッド/プロセスのCPUへの固定を含みますが、明らかな効果はありません。
仮想化を実行するとパフォーマンスが低下することが予想されます。しかし、この程度ですか?より遅い、ベアメタルサーバーがvirtよりも優れています。 5倍の8コア?
これをさらに調査して問題を特定すると、 netperf パフォーマンステストツールが、私が経験している同様のシナリオをシミュレートできることがわかりました。 netperfのTCP_CRRテストを使用して、さまざまなサーバー(仮想化と非仮想化の両方)からさまざまなレポートを収集しました。いくつかの調査結果を提供したり、私の現在のレポートを調べたい場合は、 https://Gist.github.com/985475 を参照してください。
[〜#〜] esn [〜#〜] (私の雇用主)では、Javaで記述されたComet/Web Socketサーバーである Beaconpush のプロジェクトリーダーです。これは非常にパフォーマンスが高く、最適な条件下でほとんどすべての帯域幅を飽和させることができますが、新しいTCP接続を確立できる速度に制限があります。つまり、ユーザーが頻繁に出入りする大きなユーザーチャーンがある場合、多数のTCP接続をセットアップ/ティアダウンする必要があります。私たちは、この接続を可能な限り長く維持することを軽減しようとしています。しかし、結局のところ、accept()パフォーマンスは、コアが回転しないようにするものであり、私たちはそれが好きではありません。
誰か この質問をハッカーニュースに投稿しました 、そこにもいくつかの質問/回答があります。しかし、私はこの質問を最新の情報に更新していきます。
私がこれをテストしたハードウェア/プラットフォーム:
私はこれらのテストを再実行し、レポートを https://Gist.github.com/985475 に記入している最中です。手助けをしたい場合は、数値を提供してください。それは簡単です!
(アクションプランは別の統合された回答に移動されました)
(代わりに質問自体から別の回答に移動しました)
HNのユーザー(a KVM developer?))によると、これはXenとKVMの小さなパケットパフォーマンスが原因です。これは仮想化に関する既知の問題であり、VMWareのESXはこれだけを処理します彼はまた、KVMがこれを軽減するように設計されたいくつかの新機能をもたらしていることを指摘しました( 元の投稿 )。
この情報は、それが正しい場合、少し期待を裏切ります。どちらの方法でも、Xenの第一人者が決定的な答えを出すまで、以下の手順を試してみます:)
Xen-usersメーリングリストのIain Kayがこのグラフをまとめました。 TCP_CRRバーに注目して、「2.6.18-239.9.1.el5」と「2.6.39(Xen 4.1.0を使用)」を比較してください。
Syneticon-djの提案に従って、この問題をXen固有のメーリングリストとxensourceのバグジラに送信します。 メッセージがxen-userリストに投稿されました 、応答を待っています。
単純な病理学的なアプリケーションレベルのテストケースを作成して公開します。
説明付きのテストサーバーが作成され、 GitHubに公開 されています。これにより、netperfと比較してより現実的なユースケースを見ることができるはずです。
64ビットはXenでより多くのオーバーヘッドを引き起こす可能性があるため、32ビットのPV Xenゲストインスタンスを試してください。誰かがHNでこれについて言及しました。 違いはありませんでした。
HNのabofhで提案されているように、sysctl.confでnet.ipv4.tcp_syncookiesを有効にしてみてください。カーネルでハンドシェイクが発生するため、これは明らかにmightによりパフォーマンスが向上します。 私はこれで運がありませんでした。
バックログを1024からもっと高い値に増やします。これもHNのabofhによって示唆されています。ゲストはdom0(ホスト)によって指定された実行スライス中にさらに多くの接続を受け入れる()可能性があるため、これも役立つ可能性があります。
受け入れ率が半分になる可能性があるため、すべてのマシンでconntrackが無効になっていることを再確認します(deubeulyouが推奨)。 はい、すべてのテストで無効にされました。
「netstat -sでリッスンキューのオーバーフローとsyncacheバケットのオーバーフロー」を確認します(HNのmike_esspeで推奨)。
割り込み処理を複数のコアに分割します(以前に有効にしようとしたRPS/RFSはこれを行うはずですが、もう一度試す価値があるかもしれません)。 HNのadamtから提案されました。
TCP Matte Baileyの提案によるセグメンテーションオフロードとスキャッター/ギャザーアクセラレーションをオフにする(EC2または類似のVPSホストでは不可能)
事例として、NICハードウェアアクセラレーションをオフにすると、Xenコントローラーのネットワークパフォーマンスが大幅に向上することがわかりました(LXCにも当てはまります)。
スキャッターギャザーアクセレ:
/usr/sbin/ethtool -K br0 sg off
TCPセグメンテーションオフロード:
/usr/sbin/ethtool -K br0 tso off
ここで、br0はハイパーバイザーホスト上のブリッジまたはネットワークデバイスです。起動するたびにオフにするには、これを設定する必要があります。 YMMV。
多分あなたは少し明確にすることができます-あなた自身のサーバーのXenの下でテストを実行しましたか、それともEC2インスタンスだけで実行しましたか?
Acceptは単なる別のsyscallであり、新しい接続は、最初のいくつかのパケットにいくつかの特定のフラグがあるという点でのみ異なります。Xenなどのハイパーバイザーは間違いなく違いを認識しません。セットアップの他の部分は次のようになる可能性があります。たとえばEC2では、セキュリティグループがそれと何か関係があるとしても驚かないでしょう。 conntrackも 新しい接続の受け入れ率を半減すると報告されています(PDF) 。
最後に、 最近Libratoがブログに書いた のように、CPUとカーネルの組み合わせが原因で、EC2(およびおそらく一般的にはXen)で奇妙なCPU使用率/ハングアップを引き起こすようです。
Dom0のブリッジコードでiptablesと他のフックを無効にしたことを確認してください。明らかに、それはブリッジネットワーキングXenセットアップにのみ適用されます。
echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 0 > /proc/sys/net/bridge.bridge-nf-call-arptables
それはサーバーのサイズに依存しますが、より小さなサーバー(4コアプロセッサ)に依存し、1つのCPUコアをXen dom0専用にして固定します。ハイパーバイザーの起動オプション:
dom0_max_vcpus=1 dom0_vcpus_pin dom0_mem=<at least 512M>
物理イーサネットPCIデバイスをdomUに渡そうとしましたか?ニースのパフォーマンスが向上するはずです。