pikesaku’s blog

個人的な勉強メモです。記載内容について一切の責任は持ちません。

RTTとパケロスとスループットの関係について(修正中)

参考

https://www.kimullaa.com/posts/202008220145/

wireshark統計結果のコメントを、ちゃんと調査し書く。★

ポイント

RTTは、、、
UDPスループット(転送データ量)に影響しない。
TCPスループット(転送データ量)に影響する。※上限が決まる。

第1回 FTPでスループット計測するときの注意事項 | gihyo.jp

https://gihyo.jp/assets/images/admin/serial/01/tcp-cc/0004/zu2.png

上記の表は、ウィンドウサイズの最大値が64KBである前提。
例)RTTが10msの場合
TCPはウインドウサイズ分はまとめて送るが、Ack来ないと以降のデータを送らない。
Ackが来るのに10msかかる為、10msの間に送信できる最大データは64KBになる。これを、1秒あたりにすると。
1000ms(1秒)÷10ms=100
64KB×100×8=51200000=51.2Mb/s

★超重要★ウィンドウスケーリングオプションがサポートされる場合は、ウインドウサイズは理論値で最大1GB位になる。結果として、スループットは上記表より増える。後述。

動作確認

環境

・ホストA(192.168.0.250)→スイッチ→ホストB(192.168.0.252)
・ホストA,BともにTCPセグメンテーションオフロードは無効化 ※パケットフローを確認する為。
・リンクは1Gbps/s
・ホストA→ホストBのRTTは0.367ms ※MTU値でのICMPで確認
・ホストBのデータをホストAにSCPでデータ転送する時のスループットは111.2MB/s

ホストA→ホストB

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 10 | tail -2
10 packets transmitted, 10 received, 0% packet loss, time 9219ms
rtt min/avg/max/mdev = 0.330/0.367/0.398/0.021 ms

ホストBのデータをホストAに転送(以下コマンドはホストAで実行)

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252
:/tmp/100mb.file /tmp/.
100mb.file                                                         100%  100MB 111.1MB/s   00:00    

ホストB→ホストA

# ping -s 1472 192.168.0.250 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.250 -c 10 | tail -2
10 packets transmitted, 10 received, 0% packet loss, time 9197ms
rtt min/avg/max/mdev = 0.287/0.347/0.379/0.027 ms

Case1

・RTTが10msの場合
 TCPスループットの試算
 1000ms÷10ms×64KB=6400KB/s(51.2Mb/s)

・ホストAで以下コマンド実行

# tc qdisc add dev enp0s25 root netem delay 10ms

・確認

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 10 | tail -2
10 packets transmitted, 10 received, 0% packet loss, time 9014ms
rtt min/avg/max/mdev = 10.344/10.373/10.423/0.026 ms
# 

・ホストBのデータをホストAにSCPでデータ転送する時のスループットは100MB/s。★6400KB/s(51.2Mb/s)でない。。。。★

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/.
100mb.file                                                         100%  100MB 100.9MB/s   00:00    
# 

この原因は、先述したウィンドウスケーリングオプションにより、ウィンドウサイズが64KB以上になっていた為。
TCP通信の最大ウィンドウサイズの大きさはいくつなの?最近のOS Windows Server 2008や2012では | puti se blog


https://www.kimullaa.com/posts/202008220145/
計算式
スループット(bps) = TCP Window Size(Byte) * 8(bit) / RTT(sec)

パケットキャプチャをWireSharkの"統計"→"TCPストリームグラフ"→"ウィンドウスケーリング"でみると

Windowサイズは3MB位(3144704Byte)になってる。※緑色線が受信ウィンドウサイズ。紺色線は出力バイトで、Ackを待たずに送信したバイト数(後述)
3MBの場合、
1000ms÷10ms×3MB=300MB/s
ただ、実際にAckを待たずにデータ転送したのは、出力バイトの値なので最大で1.3~1.4MBくらい。
1000ms÷10ms×1.3MB=130MB/s
SCPのスループットも、100MB/sだったので、まあ近い数字にはなる。(ずれの理由は、常に10msあたり130MB/s転送できたわけではない為)

Case2

・RTTが10msの場合
 パケロスが5%ある場合

・ホストAで以下コマンド実行

# tc qdisc add dev enp0s25 root netem delay 10ms loss 5%

・確認

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 100 | tail -2
100 packets transmitted, 97 received, 3% packet loss, time 99209ms
rtt min/avg/max/mdev = 10.313/10.391/10.447/0.031 ms
# 

・ホストBのデータをホストAにSCPでデータ転送する時のスループットは86.3MB/s

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/.
100mb.file                 100%  100MB  86.3MB/s   00:01    
# 

パケロスがあると、グラフの出力バイトの線が大きくアップダウンする

Case3

・RTTが100msの場合

・ホストAで以下コマンド実行

# tc qdisc add dev enp0s25 root netem delay 100ms

・確認

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 10 | tail -2
10 packets transmitted, 10 received, 0% packet loss, time 9013ms
rtt min/avg/max/mdev = 100.306/100.358/100.405/0.034 ms
# 

・ホストBのデータをホストAにSCPでデータ転送する時のスループットは17.1MB/s

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/.
100mb.file                 100%  100MB  17.1MB/s   00:05    
# 

遅延が大きいと、紺色線の密度が小さくなる=送信データ数が少ない=スループット低下

Case4

・RTTが100msの場合
 パケロスが5%ある場合

・ホストAで以下コマンド実行

# tc qdisc add dev enp0s25 root netem delay 100ms loss 5%

・確認

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 100 | tail -2
100 packets transmitted, 95 received, 5% packet loss, time 99191ms
rtt min/avg/max/mdev = 100.324/100.375/100.434/0.022 ms
# 

・ホストBのデータをホストAにSCPでデータ転送する時のスループットは10.2MB/s

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/.
100mb.file                 100%  100MB  10.2MB/s   00:09    
# 

パケロスがあると、グラフの出力バイトの線が大きくアップダウンする

パケットロスの発生状況を、統計→入出力グラフで確認した結果は以下の通り。※右によってるのは、2セッションの内の最後の方のみにフィルタした為。

Case5

・RTTが100msの場合(ホストA→B、ホストB→A双方で50ms遅延)
 パケロスが5%ある場合(ホストA→B、ホストB→A双方で2.5%)
※Case 4のRTT遅延、パケロスは片方向のみ。それを半分にして双方向で同程度に遅延、パケロスを発生させた場合。

・ホストA,Bで以下コマンド実行

# tc qdisc add dev enp0s25 root netem delay 50ms loss 2.5%

・確認

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 100 | tail -2
100 packets transmitted, 95 received, 5% packet loss, time 99202ms
rtt min/avg/max/mdev = 100.314/100.403/100.463/0.031 ms
# 

・ホストBのデータをホストAにSCPでデータ転送する時のスループット127.2KB/s

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/.
100mb.file                 100%  100MB 127.2KB/s   13:25    
# 


Case 4と大きく異なる結果となった。データ出力が上がらない。原因は数の多いデータ送信パケットのロスが再送処理につながりスループットに影響していると想定される。Case 6で確認

パケットロスの発生状況を、統計→入出力グラフで確認した結果は以下の通り。※右によってるのは、2セッションの内の最後の方のみにフィルタした為。

→Case4と比較し、パケロス数が圧倒的に多い

Case6

・RTTが100msの場合(ホストA→B、ホストB→A双方で50ms遅延)

・ホストA,Bで以下コマンド実行

# tc qdisc add dev enp0s25 root netem delay 50ms

・確認

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 10 | tail -2
10 packets transmitted, 10 received, 0% packet loss, time 9013ms
rtt min/avg/max/mdev = 100.375/100.402/100.429/0.019 ms
# 

・ホストBのデータをホストAにSCPでデータ転送する時のスループットは10.2MB/s

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/.
100mb.file                 100%  100MB  17.1MB/s   00:05    
# 


送信側のパケロスがない為、Case 5のようにスループット低下は発生せず。ただ、Case 3と比べアップダウンが大きい点、スループットが1.7倍異なる点は要調査

Case7

・パケロスが2.5%ある場合(ホストA→B、ホストB→A双方)

・ホストA,Bで以下コマンド実行

# tc qdisc add dev enp0s25 root netem loss 2.5%

・確認

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 100 | tail -2
100 packets transmitted, 95 received, 5% packet loss, time 101384ms
rtt min/avg/max/mdev = 0.280/0.359/0.423/0.028 ms
# 

・ホストBのデータをホストAにSCPでデータ転送する時のスループットは30.4MB/s

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/.
100mb.file                 100%  100MB  30.4MB/s   00:03    


出力バイト数が上がらず

Case8

・RTTが100msの場合
 パケロスが20%ある場合

・ホストAで以下コマンド実行

# tc qdisc add dev enp0s25 root netem delay 100ms loss 20%

・確認

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 100 | tail -2
100 packets transmitted, 81 received, 19% packet loss, time 99454ms
rtt min/avg/max/mdev = 100.295/100.366/100.432/0.028 ms
# 

・ホストBのデータをホストAにSCPでデータ転送する時のスループットは6.0MB/s

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/.
100mb.file                 100%  100MB   6.0MB/s   00:16    
# 

Case4のパケロス5%と比べ、ウィンドウサイズの出力バイトのグラフが下に張り付く

Case8

・リンクが10Mb/sの場合

・確認

# ping -s 1472 192.168.0.252 -c 1 > /dev/null 2>&1 && ping -s 1472 192.168.0.252 -c 10 | tail -2
10 packets transmitted, 10 received, 0% packet loss, time 9015ms
rtt min/avg/max/mdev = 10.434/10.502/10.536/0.029 ms
# 

・ホストBのデータをホストAにSCPでデータ転送する時のスループット694.1KB/s

# scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/. > /dev/null && scp ubuntu@192.168.0.252:/tmp/100mb.file /tmp/.
100mb.file                 100%  100MB 694.1KB/s   02:27    
# 




ウィンドウサイズが大きくなるのに、時間がかかっている。

WireSharkの統計→TCPストリームグラフ→ウィンドウスケーリングの 出力バイト(outstanding bytes)の意味

オンラインヘルプは以下説明のみ。
 Window Scaling
  Window size and outstanding bytes.
推測では、Ackなしでまとめ送りしてるデータのバイト数と想定
確認してみる。


6468番のパケットで、最大値である2000000Byte(約2MB)付近になっている。
シーケンス番号は7842537

統計→フローグラフ→TCP Flowsで

6468番のパケットの直後は、データ受信側からのAck。


6468番より前のパケットで、データ受信側からのAckは5744029

って、ことはまとめ送りしたバイト数は、

7842537 - 5744029 = 2098508

まあ、2000000付近であり辻褄合う数値。

バイト数の異なる、もう1点でも見てみる。


1527番のパケットで、1000000Byte(約1MB)付近(下振れ)になっている。
シーケンス番号は1821549

統計→フローグラフ→TCP Flowsで

1527番のパケットの直後は、データ受信側からのAck。


1527番より前のパケットで、データ受信側からのAckは910757

まとめ送りしたバイト数は、

1821549 - 910757 = 910792

まあ、1000000付近(下振れ)であり辻褄合う数値。

★結論★認識正しい