ポイント
RTTは、、、
UDPのスループット(転送データ量)に影響しない。
TCPのスループット(転送データ量)に影響する。※上限が決まる。
第1回 FTPでスループット計測するときの注意事項 | gihyo.jp
上記の表は、ウィンドウサイズの最大値が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 #
ウィンドウサイズが大きくなるのに、時間がかかっている。
他
第1回 TCPの輻輳制御とは何か | gihyo.jp
第2回 輻輳制御アルゴリズムの3タイプ | gihyo.jp
第3回 CUBIC-TCPの登場 | gihyo.jp
第4回 BBRの出現 | gihyo.jp
WireSharkでパケットロスを確認する方法
tcp.analysis.lost_segment
tcp.analysis.ack_lost_segment
tcp.analysis.flags && !tcp.analysis.window_update
問題のあるパケットをWireshark で素早く把握する方法 : tcp.analysis.flags && !tcp.analysis.window_update
【Wireshark】よく使用する表示フィルタ | hirota.noの技術ブログ〜 It's all over the network.
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付近(下振れ)であり辻褄合う数値。
★結論★認識正しい