Linux TCPの速度低下/パケット損失をデバッグする方法

Linux TCPの速度低下/パケット損失をデバッグする方法

約200KByte /秒に遅くなる特定のネットワークパスを追跡しようとしています。以下を含むさまざまなテストでこのパフォーマンスを確認しましたscprsynciperf3

$ iperf3 -c 157.130.91.64 -R
Connecting to host 157.130.91.64, port 5201
Reverse mode, remote host 157.130.91.64 is sending
[  5] local 172.16.1.177 port 47862 connected to 157.130.91.64 port 5201
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.00   sec   274 KBytes  2.25 Mbits/sec
[  5]   1.00-2.00   sec   199 KBytes  1.63 Mbits/sec
[  5]   2.00-3.00   sec   202 KBytes  1.66 Mbits/sec
[  5]   3.00-4.00   sec   198 KBytes  1.62 Mbits/sec
[  5]   4.00-5.00   sec   195 KBytes  1.60 Mbits/sec
[  5]   5.00-6.00   sec   184 KBytes  1.51 Mbits/sec
[  5]   6.00-7.00   sec   195 KBytes  1.60 Mbits/sec
[  5]   7.00-8.00   sec   209 KBytes  1.71 Mbits/sec
[  5]   8.00-9.00   sec   192 KBytes  1.58 Mbits/sec
[  5]   9.00-10.00  sec   187 KBytes  1.53 Mbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  2.31 MBytes  1.94 Mbits/sec   65             sender
[  5]   0.00-10.00  sec  1.99 MBytes  1.67 Mbits/sec                  receiver

iperf Done.

問題のホストはサードパーティのホスティングプロバイダにあります。共同配置されたデータセンターにデータをダウンロードしています。

まだ共通分母が何なのかよくわかりません。内側のネットワークには2つのルーター、VMホスト、仮想マシンがあります。 VMホストと最も内側のルーターはVxLAN(つまりip link add vxlan100 type vxlan...経由)を使用していますが、これが問題の一部であると疑われます。ただし、VxLANを使用すると、直接ラック内のさまざまな場所で1Gbitの速度(iperf3を使用して測定)を取得できます。例を挙げることができますが、上記のように読み取られ、はるかに速く読み取られます。

この時点で唯一の手がかりは、200 KByte / secトランスポートの実行中にトラフィックをキャプチャすると、WiresharkがTCP再送信、TCPアウトオブオーダー、およびTCP Dup ACKメッセージの発生率が高いことです。これは速度低下に関連しているようです。より速い速度で実行されるキャプチャトラフィックにもいくつかのTCP再送信がありますが、送信されるトラフィックと比較してはるかに少ないです。

私の質問は、パケットの欠落の原因を見つけるためにどのようにデバッグできるかということです。特に確認する必要がありますか?どのくらいパケットロスが遅くなっているようですが、どこで見つけることができるのかわかりません。パケット損失自体は遅い速度では発生せず、データセンター内のシステム内でも発生しません。このようなことが起こると予測できる正確な単一の場所はないようです。これは、私のデータセンターの仮想マシンと他のデータセンターの別のマシンの間で確実に発生するだけです。 (そして、この他のマシンは、AWSなどの他の場所への転送速度が高いため、サードパーティのマシンです。私が確認した結果、ネットワークに転送したときにのみ再生されます。)

どんなアイデアがありますか?

答え1

子孫のためにこの問題をどのように解決したかについての後続の回答を投稿します。私は、パケット損失を追跡したい他の人に役立ついくつかの手順を実行しました。

iperf3問題を再現するための素晴らしいツールです。

仕える人:iperf3 -s

クライアント:(iperf3 -c 157.130.91.64 -Rまたは-Rなしで別の方向に移動)

tcpdumpその後、パケットをファイルに記録しましたが、アクセスできるすべてのポイントで同時にこのパケットキャプチャを実行します。。ホスト間で2つのLinuxルーターを制御し、VxLANが独自のインターフェースを使用していたので、最終的に9つの別々のポイントを取得し、次のコマンドを使用してキャプチャしました。

tcpdump -w /tmp/machineX-eno1.cap

その後、scpこのファイルをデスクトップで編集し、ブリトーを入手し、Wireshark UIを使用して9つの異なるサンプルをシャッフルし、ストリーミングパケットが失われる正確な場所を見つけました。 (WiresharkはUIとして非常に優れているため、内部のTCPフローを表示できるようにVxLANトラフィックの解凍などの操作を実行できますが、コピーして貼り付けるための素晴らしいテキストtcpdump出力を提供するため、以下の例ではこれを使用します。 )

リンクが飽和するとパケット損失が発生するのは正常ですが、この場合は予想よりもはるかに早く損失が発生します。 TCPの場合、「ウィンドウ」は「承認が必要になる前に送信できるデータ量」を追跡するために使用されます。ウィンドウは適切なサイズで始まり、パフォーマンスが向上し、パケット損失がなくなるにつれて増加します。すべての状況で、最初に失われたパケットはストリームで数メガバイトだけ発生します。ただし、問題の場合、パケット損失が発生する前に約260kのデータしかストリームに送信できません。

私の例に示すように、tcpdump -n -r [filename]クライアントシステムでのパケット損失は次のとおりです。

13:40:00.344219 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 246161:253401, ack 38, win 227, options [nop,nop,TS val 4032728542 ecr 187200696], length 7240
13:40:00.344232 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 253401, win 2745, options [nop,nop,TS val 187200770 ecr 4032728542], length 0
13:40:00.345642 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 253401:260641, ack 38, win 227, options [nop,nop,TS val 4032728542 ecr 187200696], length 7240
13:40:00.345673 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 260641, win 2858, options [nop,nop,TS val 187200771 ecr 4032728542], length 0
13:40:00.345772 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 260641:269329, ack 38, win 227, options [nop,nop,TS val 4032728542 ecr 187200696], length 8688

上記の最後のパケットまでは、すべてが大丈夫に見えます。示されているように、ストリームのオフセット269329に送信されることがわかりますseq 260641:269329。問題は次のパケットを待っています。

13:40:00.345772 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 301185:304081, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896

マブソサ、269329から301184までのデータはどこに行きましたか?まさに。次のパケットに表示されるデータですseq 301185:304081。時々、パケットは順番に到着するかもしれませんが、ストリームを見ても問題になるデータは明らかになりません。

私たちは以下を見てこれを確認しますack

13:40:00.345805 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 2994, options [nop,nop,TS val 187200771 ecr 4032728542], length 0
13:40:00.345857 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3039, options [nop,nop,TS val 187200771 ecr 4032728542,nop,nop,sack 1 {301185:304081}], length 0
13:40:00.345934 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 304081:306977, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896
13:40:00.345934 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 306977:309873, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896
13:40:00.345934 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 309873:312769, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896
13:40:00.345935 IP 157.130.91.64.5201 > 172.16.1.177.50298: Flags [.], seq 312769:314217, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 1448
13:40:00.345971 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3084, options [nop,nop,TS val 187200771 ecr 4032728542,nop,nop,sack 1 {301185:306977}], length 0
13:40:00.345995 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3129, options [nop,nop,TS val 187200772 ecr 4032728542,nop,nop,sack 1 {301185:309873}], length 0
13:40:00.346005 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3175, options [nop,nop,TS val 187200772 ecr 4032728542,nop,nop,sack 1 {301185:312769}], length 0
13:40:00.346011 IP 172.16.1.177.50298 > 157.130.91.64.5201: Flags [.], ack 269329, win 3197, options [nop,nop,TS val 187200772 ecr 4032728542,nop,nop,sack 1 {301185:314217}], length 0

クライアントからサーバーに再送信する繰り返し転送を表示できますack 269329。これは、クライアントがストリーム内の対応するポイントより前にパケットセット全体を受信し、その後のデータが欠落していることを示します。

これで、ルータ(「次ホップ」)でtcpdumpをチェックすると、実際に受信(および転送)されていることがわかります。これは着信インターフェイスからのものであるため、NATによって宛先IPが異なりますが、送信には次のものが表示されます。同じデータパック):

13:40:00.356167 IP 157.130.91.64.5201 > 32.133.287.15.50298: Flags [.], seq 253401:273673, ack 38, win 227, options [nop,nop,TS val 4032728542 ecr 187200696], length 20272
13:40:00.356235 IP 157.130.91.64.5201 > 32.133.287.15.50298: Flags [.], seq 273673:293945, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200696], length 20272
13:40:00.356291 IP 157.130.91.64.5201 > 32.133.287.15.50298: Flags [.], seq 293945:301185, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 7240
13:40:00.356367 IP 157.130.91.64.5201 > 32.133.287.15.50298: Flags [.], seq 301185:304081, ack 38, win 227, options [nop,nop,TS val 4032728543 ecr 187200697], length 2896

したがって、ルータは自分がパケットを送信すると考え、ホストはパケットを受信しないことが明らかです。

さらなる調査を通して、私はこのパズルのもう一つの非常に興味深い部分を見つけました。

  • これらのパケットはMTUである1500バイトより大きいです。 1500 MTU はリンク層に含まれないため、イーサネットヘッダも含まれません。ところでこのパケットがまだ20k程度なのにこれがなんだ..
  • これは、一括送信オフロード/LSO(一括受信オフロード/LROの場合はその逆)によるものです。これにより、オペレーティングシステムはデフォルトでこれらの大規模パケットをネットワークカードに送受信できます。ネットワークカードは必要なヘッダー(TCPヘッダーを含む)を書き換えて、MTUと一致する意味で同じパケットセットを形成します。したがって、オペレーティングシステムは20kデータパケットを送信し、ネットワークカードは12個のデータパケットをパンチして外部に送信します。各データパケットは1500バイト未満です。受信するときはその逆です。
  • LSO、LRO、およびその他のハードウェア最適化を無効にできます。方程式からそれらを削除し、送信される内容をよりよく理解するには、ethtool次のようにします。ethtool -K enp12s0 rx off tx off sg off tso off gso off gro off lro off rxvlan off txvlan off rxhash off
  • 私が知っている限り、これは実際には改善されますが、十分ではありません。 1.5Mbitではなく1Gbitネットワークカードから10Mbitを取得します。
  • ethtoolエラーの検索にも使用できます。、例えばethtool -S enp12s0 | grep err- これは興味深い結果を生み出すことができます。見つかった個々のエラー(存在する場合)を調べてください。これが問題の原因である可能性があります。
  • 場合によっては、ルータの1つでtcpdumpを使用してキャプチャするときにtcpdumpを実行すると、パフォーマンスが向上する可能性があります。(これは私にとってとても奇妙です)。明らかに、これはいくつかのバッファが早くフラッシュされるなどの理由で発生する可能性がありますが、この時点でどのデバイスに問題があるかはかなり明らかになりました。パケットロギングを実行してパフォーマンスが大幅に向上した場合、監視しているデバイスが問題の原因です。
  • また、ケーブル、SFPアダプタ、スイッチポートなどを確認することをお勧めします。(私の場合は、どちらも問題になりませんでした)

ポイント:パケットをダンプし、ネットワーク上の問題のある場所を絞り込み、上記の考え方や考えられる他の方法を使用して根本的な原因であることを確認し、iperf3を使用して条件を簡単にシミュレートして何を決定するかを確認します。意図した(またはさらに意図しない)効果を得るために変更されました。

私の場合、Linuxルーターとして使用していたマシンは信頼できないソースから購入しました(直接名前を指定しませんが、「blaamazon」と韻が似ています)、ethtoolでエラーが表示されていました。ただし、このルータを通過するほとんどのトラフィックは問題なく、特定のトラフィックパターンだけが上記のパケット損失によって困難になることに注意する価値があります。したがって、一時的な接続テストはすべて通過しますが、特定の負荷ではパケットが失われ、接続速度が遅くなります。ただし、最終的には上記の手順で制御できないデバイスが見つかり、削除されました。

関連情報