ストリーミングネットワークアプリケーションのLinuxでソケットバッファサイズを増やす正しい方法を理解しようとしています。アプリケーションは、多数のUDPソケットでストリームされた可変ビットレートデータを受信します。データの量は、ストリームの開始時に、実質的に高く、私が使用してきました:LInux上のUDPソケットのソケットごとのバッファをプログラムで増やす方法はありますか?
# sar -n UDP 1 200
をUDPスタックは、各ソケットを示すために、パケットと
# ss -un -pa
を破棄されたことを示すためにRecv-パケットが破棄される前に、Qの長さがほぼ限界(124928からsysctl net.core.rmem_default
)に増加します。これは、アプリケーションが単にストリームの開始に追いつかないことを意味します。十分な初期パケットを破棄した後、データレートが低下し、アプリケーションが追いつく。 Recv-Qは0に向かって傾向があり、その期間中そこにとどまる。
rmem_defaultの値を大幅に増やしてソケットのバッファサイズを増やし、大きな初期バーストから回復するためのアプリケーション時間を与えることで、パケット損失に対処できます。私の理解は、これがシステム上のすべてのソケットのデフォルト割り当てを変更することです。むしろ、特定のUDPソケットの割り当てを増やし、グローバルデフォルトを変更しないでください。
私の最初の戦略は、rmem_maxを修正し、個々のソケットごとにsetsockopt(SO_RCVBUF)を使用することでした。しかし、このquestionは、UDPだけでなく、すべてのソケットに対してLinuxオートチューニングを無効にすることを心配しています。
udp(7)はudp_mem設定について説明していますが、これらの値がrmem_defaultとrmem_maxの値とどのように作用するのか混乱しています。使用する言語は「すべてのソケット」なので、これらの設定は個々のUDPソケットではなく、完全なUDPスタックに適用されるという疑いがあります。
udp_rmem_minは私が探している設定ですか?それは個々のソケットに適用されるようですが、システム上のすべてのUDPソケットに適用されます。
グローバル設定を変更せずにアプリケーションで使用されている特定のUDPポートのソケットバッファ長を安全に増やす方法はありますか?
ありがとうございました。
[Linuxで実行時にUDP受信バッファサイズを指定する]の複製が可能(http://stackoverflow.com/questions/2090850/specifying-udp-receive-buffer-size-at-runtime-in-linux) –
IfこれはWindowsで、スタックオーバーフローIO、好ましくはIOCPに移行して、スタックを実行しているカーネルスレッドが提供するユーザーバッファに直接データを受け取れるようにしています。 100個の64Kバッファのプールを作成し、いくつかの重複した読み込みをキューに入れてください。確かに、Linuxでも同様のことが可能ですか? NIO/asio? –
UDP-recv()ループを受信パケット以外の何もしない別の高優先度のスレッドに移動し、実際の処理のためにメインスレッド(または他のスレッド)に渡してください。私の経験では、アプリケーションが入ってくるUDPに追いつくことができないときは、CPUが一般的には十分に速くないためではなく、受け取っているスレッドがときどき何か他のことをしていて、recv()すぐに十分です。recv()とそれ以外のスレッドを専用にすることで、そのようなホールドオフの可能性を最小限に抑えることができます。 –