一連の負荷テストを実行して、次のセットアップのパフォーマンスを判断しています。
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
特定のテストケースでは、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で無差別モードの可能な設定をすべて試しました(サーバーのオンとクライアントのオフ、サーバーのオフとクライアントのオン、両方のオン、両方のオフ)。これは違いはありませんでした。
ifconfig eth0 promisc
有効またはifconfig eth0 -promisc
無効にします。違いがある場合は、両方のマシンで無差別オン/オフの4つの可能な組み合わせを比較してみてください。それは問題の原因を特定するのに役立つかもしれません。
-p
オプションを渡して、それをスキップして違いが生じるかどうかを確認することができます。