1

高いパフォーマンスが要求されるサーバーを作成しようとしています。この質問は、サーバー コアを扱います。高速なパフォーマンスをサポートするのに最適なプログラミングのアイデアは何ですか?

  1. ソケットを異なるスレッドに分割し、それぞれでブロッキング recv() を呼び出しますか?
  2. select() ループに座って、別のスレッドに個々のポートを処理するように通知する 1 つのスレッドがありますか?
  3. select() と応答を処理するスレッドが 1 つありますか?
  4. 2 つまたは 3 つを行いますが、すべてのポートではなくポートのクラスターを使用しますか?
  5. 上で指定したように select を使用する場合、ブロッキング ポートと非ブロッキング ポートの使用は重要ですか?
  6. TCP_NODELAY など、どのような setsockopt がパフォーマンスを向上させますか?

これらのいくつかはユースケースに依存することを認識しています。たとえば、TCP_NODELAY をオフにした 6 は、小さなパケットが多数ある場合に悪影響を及ぼします。3 は、応答が些細な場合に高速になる可能性があるように聞こえます。パフォーマンスに影響を与えるとは思わなかった他の質問も歓迎します。

4

3 に答える 3

3

シングルスレッドのアプローチから始めます。ノンブロッキング I/O と、Linux のエッジ トリガー epoll のような高速ポーリング メカニズムを使用します。(他のプラットフォームにも同様のテクノロジがあります。) ポーリング ループを中心にすべてを集中させると、プログラムの設計が大幅に簡素化されます。その後、すべてが 1 つの中央ループによって処理されます。

マルチスレッド化が必要な場合は、メイン ループを複数回同時に実行するだけで簡単に実行できます。イベントを「ワンショット」に設定すると、それらは再準備されるまでポーリングから無効になるため、イベントを処理するスレッドは、イベントを処理する唯一のスレッドであると安全に想定できます (そして最後にイベントを再準備します) )。プログラムの異なる部分間の通信、または共有データ アクセスを同期するだけで済みますが、多くの同期は既にポーラーによって処理されています。

于 2012-11-01T01:31:36.350 に答える
2

私の意見では、最も簡単にコーディングできるのは、ブロッキング I/O を使用して接続ごとに 1 つのスレッドです。また、お気に入りのスレッド モデルを使用して、ポータブルに書き込むことも簡単です。

非ブロッキング I/O を多重化する際の問題は、各接続の状態を維持することです。たとえば、1024 バイトを書き込みたいのですがwrite、消費したのは 900 バイトだけです。後で書き込むために、124 バイトを覚えておく必要があります。そして、それは生の「バッファの送信」レベルでの状態です。プロトコル全体の状態を考慮すると、すぐに複雑になる可能性があります。もちろん、不可能なことは何もありませんが、接続が相互に対話する必要が (あまり) ないと仮定すると、ブロッキング呼び出しを使用する方がはるかに簡単です。

私はこのアプローチを適度な数 (~数十) の接続に使用し、10GbE リンクのペアで 1 秒あたり 1 ギガバイトを超える速度でデータを移動しました。Linux カーネルのスケジューラは、この範囲のスレッド数をうまく処理できます。

数千または数万のクライアントにサービスを提供する Web サーバー タイプのものについては... まあ、私は個人的には試していません。そのシナリオでは、多重化手法(epollなど)の方が高速であることを読みました。他の人が言ったように、それはあなたのアプリケーションに依存します。

しかし、あなたのアプリケーションが私のようなものである場合 (接続の数が少なく、それらの間の相互作用が限られている)、「接続ごとに 1 つのスレッド」アプローチが勝ちます、IMO。

于 2012-11-01T02:19:03.800 に答える
0

場合によります。

このタイプの質問は、答えるのが非常に難しいです。それがプロジェクト自体の役割の1つになります。サーバーが直面する作業負荷の下でサーバーのパフォーマンスを測定しユースケースに最適なオプションを確認する必要があります。

たとえば、TCP_NODELAY を設定するとリクエストの待ち時間が短縮されますが、そのオプションには理由があります。TCP_NODELAY を設定すると、スループットが低下します。

http://www.kegel.com/c10k.html . _ その一部は現在 (数年) 少し古いものですが、使用を検討すべきテクノロジのリストが含まれています: epoll、非同期 I/O。

ワーカーが特定の実装 (select/poll/epoll) に縛られないように、モジュール方式でシステムを設計することに着手する必要があります。setsockopt のようなものは後で簡単に変更できるので、まったく気にする必要はありません。

最初に機能させてから、「高速」にします。「速い」の意味は何でも。スケーリングするものが必要な場合は、アルゴリズムの大きな O (O(n)、O(n^2) ... など) に注意してください。

于 2012-11-01T01:43:30.160 に答える