0

オブジェクトに対して INSERT/READ/UPDATE/DELETE 操作のみを実行するキャッシュ アプリケーション (memcached に類似) 用に UDP (Linux で) を介して独自のプロトコルを開発していますが、どの設計が最適かわかりません。

  1. パケットごとに 1 つの要求を送信します。(クライアントはリクエストを準備し、すぐにサーバーに送信します)
  2. パケットごとに複数のリクエストを送信します。(クライアントはパケット内の要求をキューに入れ、満杯 (MTU サイズに近い) になると、それをサーバーに送信します)

リクエストのサイズ (つまり、レコード データ) は 32 バイトから 1400 バイトまでです。平均的にどれくらいになるかはわかりません。ユーザーのアプリケーションに完全に依存します。

  1. パケットごとに単一のリクエストを選択すると、多数の小さなパケットを管理する必要があり、カーネルが何度も中断されます。これにより、ユーザー空間からシステムに切り替えるときにカーネルがレジスターを保存する必要があるため、操作が遅くなります。また、ユーザーのアプリケーションが 32 バイト (udp のパケット オーバーヘッドは約 28 バイト) の要求を多数送信すると、ネットワーク トラフィックが 2 倍になり、伝送速度に大きな影響を与えます。ただし、NIC には独自のプロセッサがあり、CPU が停止することはないため、ネットワーク トラフィックが多いからといってパフォーマンスが低いとは限りません。ネットワークのボトルネックが発生した場合に備えて、追加のネットワーク カードを取り付けることができます。単一パケットを使用することの大きな利点は、サーバーとクライアントが非常に単純であるため、命令を節約して速度を上げることができることです。

  2. パケットごとに複数のリクエストを使用すると、パケットは少なくなりますが、より大きなパケットになるため、ネットワーク経由でより多くのデータを送信できます。システム コールの数は減りますが、サーバーが複雑になると、より多くのメモリとより多くの命令を実行する必要があるため、この方法でより高速に実行できるかどうかは不明です。CPUがボトルネックになることもあるかもしれませんが、CPUを追加するのとネットワークカードを追加するのとではどちらが安いのでしょうか?

アプリケーションには、最新の CPU で 1 秒あたり 100,000 リクエストなど、重いデータ負荷が必要です。私はそれを行う方法がわかりません。「パケットごとに 1 つのリクエスト」にしようと考えていますが、複数のリクエストを処理するために既に書いたすべてのコードを書き直す前に、推奨事項を尋ねたいと思います。

前もって感謝します。

4

2 に答える 2

1

遅延帯域幅のどちらを重視しますか?

  • 遅延が発生した場合は、パケットの最後に多くの「スラック」が発生し、全体的により多くのパケットが発生することを意味する場合でも、できるだけ早くリクエストを送信します。
  • 帯域幅の場合は、複数の要求をまとめて「たるみ」をなくし、全体的に送信するパケットを減らします。

注: どちらの場合も、非常に高速なネットワークを使用していない限り、CPU ではなくネットワークが主なボトルネックになる可能性があります。その場合でも、データベースの INSERT/READ/UPDATE/DELETE は、パケットに必要な CPU 作業よりも多くの CPU と I/O を消費する可能性があります。

于 2012-07-15T09:39:26.830 に答える
0

パケットごとに複数のリクエストを送信することのもう 1 つのトレードオフは、

  • 一方では、UDP の信頼性の低い性質により、一度に複数の要求がドロップされる可能性があり、再送信のコストが高くなります。
  • 一方、カーネルがデータを配信するために使用するバッファーが少なくなるため、データ ドロップの可能性が低くなります。

ただし、NIC、スイッチ、ルーターのバッファー サイズ、およびその他のネットワーク ハードウェアなど、展開アーキテクチャを理解していなければ、分析は不完全です。

ただし、推奨されるのは、比較的単純な実装 (パケットごとに 1 つの要求) から開始することですが、必要に応じて複雑さを追加することがそれほど難しくないようにコードを記述することです。

于 2012-07-14T20:37:35.760 に答える