web-dev-qa-db-ja.com

UDPパケットドロップ-INErrors対.RcvbufErrors

考えられるネットワークのボトルネックについて詳しく理解するために、簡単なUDPサーバープログラムを作成しました。

UDPサーバー:UDPソケットを作成し、指定されたポートとアドレスにバインドして、ソケットファイル記述子をepollインタレストリストに追加します。次に、そのepollは着信パケットを待ちます。着信パケット(EPOLLIN)を受信すると、パケットを読み取り、受信したパケットの長さを出力するだけです。とてもシンプルですよね:)

UDPクライアント:以下に示すようにhpingを使用しました:

hping3 192.168.1.2 --udp -p 9996 --flood -d 100

毎秒100パケットでudpパケットを送信すると、UDPパケットの損失は見つかりません。しかし、(上記のコマンドに示されているように)udpパケットをフラッディングすると、重大なパケット損失が発生します。

Test1:26356パケットがUDPクライアントからフラッディングされると、サンプルプログラムは12127パケットのみを受信し、残りの14230パケットは/に示すようにカーネルによってドロップされます。 proc/net/snmp出力。

cat/proc/net/snmp | grep Udp:
Udp:InDatagrams NoPortsInErrorsOutDatagramsRcvbufErrorsSndbufErrors
UDP:12372 014230218142300

Test1の場合、パケット損失率は約53%です。

クライアント側とサーバー側の両方で「ethtool-SethX」コマンドを使用して、ハードウェアレベルで大きな損失がないことを確認しましたが、applnレベルでは、上記のように53%の損失が見られます。

したがって、パケット損失を減らすために、私はこれらを試しました:
- renice コマンドを使用して、サンプルプログラムの優先度を上げました。
-受信バッファサイズの増加(システムレベルとプロセスレベルの両方)

優先度を-20に上げます。

renice -20 2022
2022(プロセスID)古い優先度0、新しい優先度-20

受信bufサイズを16MBに増やします。

プロセスレベルで:
int sockbufsize = 16777216;
setsockopt(sockfd、SOL_SOCKET、SO_RCVBUF、(char *)&sockbufsize、(int)sizeof(sockbufsize))
カーネルレベルで:
cat/proc/sys/net/core/rmem_default
16777216
cat/proc/sys/net/core/rmem_max
16777216

これらの変更後、Test2を実行しました。

Test2:1985076パケットがUDPクライアントからフラッディングされると、サンプルプログラムは1848791パケットを受信し、残りの136286パケットは/ procに示すようにカーネルによってドロップされます。/net/snmp出力。

cat/proc/net/snmp | grep Udp:
Udp:InDatagrams NoPortsInErrorsOutDatagramsRcvbufErrorsSndbufErrors
UDP:1849064 01362862360

Test2の場合、パケット損失率は6%です。

パケット損失が大幅に削減されます。しかし、私は次の質問があります:

  1. パケットロスをさらに減らすことはできますか?!?私はここで貪欲であることを知っています:)しかし、私はパケット損失をさらに減らすことが可能かどうかを調べようとしています。
  2. Test1とは異なり、Test2ではInErrorsはRcvbufErrorsと一致せず、RcvbufErrorsは常にゼロです。誰かがその背後にある理由を説明できますか?!? InErrorsとRcvbufErrorsの違いは正確には何ですか。私はRcvbufErrorsを理解していますが、InErrorsは理解していません。

あなたの助けと時間をありがとう!!!

20
Bala

Linuxカーネルのネットワークスタックを調整してパケットドロップを減らすには、ドライバーからネットワークに至るまでの調整オプションがたくさんあるため、少し複雑です。スタック。

長いブログ投稿 すべてのチューニングパラメータを上から下に説明し、/proc/net/snmpの各フィールドの意味を説明して、これらのエラーが発生している理由を理解できるようにしました。見てください、それはあなたがあなたのネットワークを0に落とすのを助けるべきだと思います。

7
Joe Damato

ハードウェアレベルでドロップがない場合は、ほとんどがメモリの問題であるはずです。カーネル構成パラメータを微調整して0ドロップに到達できるようにする必要があります(明らかに、受信しているネットワークトラフィックに対して適切なバランスの取れたハードウェアが必要です)。 )。

私はあなたが欠けていると思います netdev_max_backlog これは着信パケットにとって重要です:

インターフェイスがカーネルが処理できるよりも速くパケットを受信したときに、INPUT側でキューに入れられるパケットの最大数。

1
Alex

InErrorsは次のもので構成されています。

  • 破損したパケット(不正なヘッダーまたはチェックサム)
  • フルRCVバッファサイズ

したがって、バッファオーバーフローの問題(RcvbufErrorsは0)が修正され、チェックサムが正しくないパケットが残っていると思います。

0
George Atsev