web-dev-qa-db-ja.com

tcpdumpはudpのパフォーマンスを向上させます

次のセットアップのパフォーマンスを確認するために、一連の負荷テストを実行しています。

Node.js test suite (client) --> StatsD (server) --> Graphite (server)

つまり、node.jsテストスイートは、x秒ごとに一定量のメトリックを別のサーバーにあるStatsDインスタンスに送信します。次にStatsDは、同じサーバーにあるGraphiteインスタンスに毎秒メトリックをフラッシュします。次に、テストスイートによって実際に送信されたメトリックの数と、グラファイトによって受信されたメトリックの数を調べて、テストスイートとグラファイトの間のパケット損失を判断します。

ただし、20〜50%の範囲の非常に大きなパケットドロップ率(UDPプロトコルで送信されていることに注意してください)が発生する場合があることに気付きました。それで、これらのパケットがドロップされている場所を調べ始めたのは、StatsDのパフォーマンスの問題の可能性があるためです。そこで、システムのすべての部分でメトリックのロギングを開始し、このドロップが発生した場所を追跡しました。そして、これは物事が奇妙になる場所です。

tcpdump を使用して、テストの実行後に検査するキャプチャファイルを作成しています。しかし、tcpdumpを実行してテストを実行すると、パケット損失はほとんどありません。 tcpdumpがどういうわけか私のテストのパフォーマンスを向上させているようで、なぜ、どのようにこれを行うのか理解できません。次のコマンドを実行して、サーバーとクライアントの両方でtcpdumpメッセージをログに記録しています。

tcpdump -i any -n port 8125 -w test.cap

1つの特定のテストケースでは、40000メトリック/秒を送信しています。 tcpdumpの実行中のテストのパケット損失は約4%ですが、テストのないテストのパケット損失は約20%です。

どちらのシステムも、次の設定でXen VMとして実行されています。

  • Intel Xeon E5-2630 v2 @ 2.60GHz
  • 2GB RAM
  • Ubuntu 14.04 x86_64

潜在的な原因についてすでに確認したこと:

  • UDPバッファーの受信/送信サイズを増やします。
  • テストに影響を与えるCPU負荷。 (最大負荷40〜50%、クライアント側とサーバー側の両方)
  • 「any」ではなく特定のインターフェイスでtcpdumpを実行する。
  • 無差別モードを無効にするには、 '-p'を指定してtcpdumpを実行します。
  • サーバーでのみtcpdumpを実行します。これにより、20%のパケット損失が発生し、テストには影響がないようです。
  • クライアントでのみtcpdumpを実行します。これにより、パフォーマンスが向上しました。
  • Netdev_max_backlogとnetdev_budgetを2 ^ 32-1に増やします。これは違いがありませんでした。
  • すべてのNICでプロミスキャスモードの可能な設定をすべて試しました(サーバーオンとクライアントオフ、サーバーオフとクライアントオン、両方オン、両方オフ)。これは違いがありませんでした。
13
Ruben Homs

Tcpdumpの実行中は、着信フレームの読み取り時にかなりプロンプトが表示されます。私の仮説は、NICのパケットリングバッファー設定が小さいサイズのビットかもしれないというものです。 tcpdumpの実行中は、よりタイムリーに空になります。

Red Hatサブスクライバーの場合、このサポート記事は非常に役立ちます パケット受信の概要 。そこにはまだあなたが考慮していないと思うことがいくつかあります。

システムがIRQを処理する方法を検討してください。ネットワークインターフェイスの 'dev_weight'を増やすことを検討してください(NICからユーザースペースに読み取られるパケットが増えることを意味します);アプリケーションがソケットを読み取る頻度を確認します(専用スレッドを使用できるか、スケーラビリティに関する既知の問題/回避策があります)。

NICフレームバッファを増やします(ethtoolコマンドを使用して---set-ringなどの引数)。

「受信側のスケーリング」を見て、少なくともその数の受信スレッドを使用してトラフィックを読み取ります。

Tcpdumpは パケットリングバッファ のカーネルサポートを使用するなど、何かクールなことをしているのでしょうか。それはあなたが見ている行動を説明するのに役立ちます。

10
Cameron Kerr

どのパワーガバナーを使用していますか? 「オンデマンド」または「保守的な」ガバナーでも同様の動作が見られます。

「パフォーマンス」ガバナーを使用して、サーバーBIOSの省電力機能を無効にしてみてください。

それは何かを変えますか?

2
shodanshok

受信側はパケットレートを処理できないだけだと思います。その理由は次のとおりです。

  1. クライアント上でtcpdumpを使用するとドロップされるパケットが減少します。tcpdumpはクライアントの速度を低下させているため、サーバーではパッカーレートがはるかに低く、それでも部分的に扱う。クライアントとサーバーの両方でRX/TXパケットカウンターをチェックして、この仮説を確認できるはずです。

  2. uDPバッファーの受信/送信サイズを増やしたとおっしゃっていましたが、詳細を教えていただけますか?サーバーでrmem_maxrmem_defaultの両方を変更することが重要です。例:sysctl -w net.core.rmem_max=524287 sysctl -w net.core.wmem_max=524287 sysctl -w net.core.rmem_default=524287 sysctl -w net.core.wmem_default=524287

設定をテストする

Statsdとノードアプリケーションを停止し、システムがアイドル状態のときに iperf を使用して、ネットワーク/カーネルが処理できるパケットレートをテストします。 iperfで40Kパケット/秒をストリーミングできても、statsdではストリーミングできない場合は、statsdのチューニングに集中する必要があります。

その他の調整パラメータ

また、net.core.netdev_max_backlogを調整することを忘れないでください。特定のインターフェイスがカーネルが処理できるよりも速くパケットを受信したときに、キューに入れられる最大パケット数。

1
unicoletti

もう1つの方法はip_conntarckモジュールです。linux-boxが新しい接続を受け入れてもよろしいですか?テスト:

root@debian:/home/mohsen# sysctl net.ipv4.netfilter.ip_conntrack_max
net.ipv4.netfilter.ip_conntrack_max = 65536
root@debian:/home/mohsen# sysctl  net.ipv4.netfilter.ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 29

テストする必要があります

net.ipv4.netfilter.ip_conntrack_max >  net.ipv4.netfilter.ip_conntrack_count

max == countの場合、最大接続はフルであり、linux-boxは新しい接続を受け入れることができません。
ip_conntrackがない場合は、modprobe ip_conntrackから簡単にロードできます

1
PersianGulf