我在使用环回接口时看到重新传输/无序数据包,并且已经搜索了好几天试图确定我是否应该对此感到惊讶(我是)或者是否其他人看到它,但我没有没有找到任何答案。抱歉,如果我只是遗漏了一些东西。有人提到了环回规范,但我找不到。
这是我正在做的一件事(在几个现代 Linux 内核上尝试过,包括 5.5.4):
sudo tcpdump -s78 -wt.tcpdump -ilo port 7001 & tcpdump_pid=$!; \
taskset -c 1 ./tcp_loopback.py -s -b1048576 & sleep .5; taskset -c 2 ./tcp_loopback.py -c -b1048576 --count=8192; \
sudo kill $tcpdump_pid; \
tshark -r t.tcpdump | egrep -i 'retrans|out.of.order' | tail
tcp_loopback.py 脚本位于 home.fnal.gov/~ron/tcp_loopback.py
服务器部分 (-s) 的核心是:
sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
sock.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
sock.bind( ('127.0.0.1', port) )
sock.listen( 4 )
sockconn,address = sock.accept()
while 1:
data = sockconn.recv(bs)
if opargs['-v']=='': print('received: '+str(len(data)))
if len(data) == 0:
if opargs['-v']=='': print('0 data, closing')
break
客户端部分 (-s) 的核心是:
sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
sock.connect( ('127.0.0.1',port) )
for xx in range(cnt): sock.send( '*'*bs )
重新传输的概率似乎随着更大(即 2M、4M)的写入/读取而增加。
我已阅读(例如 Documentation/networking/scaling.rst)关于与不同内核上的调度相关的无序问题,因此使用了上面的“任务集”。
有没有办法防止这种情况发生(同时仍然以高速率使用大写/读)?
使用环回,我真的不知道我是在查看发送处理发送乱序的东西还是接收处理接收乱序的东西。我的最终目标是在 100 Gi、高拥塞(多对一)环境中建立低延迟节点间传输的基线。我开发了一个应用程序,它使用“调试套接字”来获取重传信息,我很惊讶地看到 localhost 上的重传。
谁能帮我理解发生了什么,以及是否有任何旋钮(例如 sysctl)可以转动以消除重传,同时仍然最大限度地提高数据速率?
谢谢,罗恩
PS当我这样做时,我最终也看到了这个问题:
while true;do
sudo tcpdump -s78 -w/tmp/t.tcpdump -ilo port 7001 & tcpdump_pid=$!
ncat -4l localhost 7001 > /dev/null & ncat_pid=$!
sleep .5
dd if=/dev/zero bs=1048576 count=2048 | ncat localhost 7001
sudo kill $tcpdump_pid
tshark -r /tmp/t.tcpdump | egrep -i 'retrans|out.of.order' && break
done
示例输出:
/home/ron/notes
ron@ronlap77 :^) sudo tcpdump -s78 -wt.tcpdump -ilo port 7001 & tcpdump_pid=$!; \
> taskset -c 1 ./tcp_loopback.py -s -b1048576 & sleep .5; taskset -c 2 ./tcp_loopback.py -c -b1048576 --count=8192; \
> sudo kill $tcpdump_pid; \
> tshark -r t.tcpdump | egrep -i 'retrans|out.of.order' | tail
[1] 29066
[2] 29067
tcpdump: listening on lo, link-type EN10MB (Ethernet), capture size 78 bytes
191379 packets captured
383230 packets received by filter
0 packets dropped by kernel
[2]+ Done taskset -c 1 ./tcp_loopback.py -s -b1048576
189947 1.092534 127.0.0.1 → 127.0.0.1 TCP 65549 [TCP Out-Of-Order] 46988 → 7001 [ACK] Seq=4203412074 Ack=1 Win=65536 Len=65483 TSval=2693245609 TSecr=2693245609
189948 1.092535 127.0.0.1 → 127.0.0.1 TCP 65549 [TCP Out-Of-Order] 46988 → 7001 [ACK] Seq=4203477557 Ack=1 Win=65536 Len=65483 TSval=2693245609 TSecr=2693245609
189949 1.092536 127.0.0.1 → 127.0.0.1 TCP 65549 [TCP Out-Of-Order] 46988 → 7001 [ACK] Seq=4203543040 Ack=1 Win=65536 Len=65483 TSval=2693245609 TSecr=2693245609
189950 1.092536 127.0.0.1 → 127.0.0.1 TCP 65549 [TCP Out-Of-Order] 46988 → 7001 [ACK] Seq=4203608523 Ack=1 Win=65536 Len=65483 TSval=2693245609 TSecr=2693245609
189951 1.092537 127.0.0.1 → 127.0.0.1 TCP 65549 [TCP Out-Of-Order] 46988 → 7001 [ACK] Seq=4203674006 Ack=1 Win=65536 Len=65483 TSval=2693245609 TSecr=2693245609
189962 1.092594 127.0.0.1 → 127.0.0.1 TCP 65549 [TCP Spurious Retransmission] 46988 → 7001 [ACK] Seq=4203674006 Ack=1 Win=65536 Len=65483 TSval=2693245609 TSecr=2693245609
190115 1.093456 127.0.0.1 → 127.0.0.1 TCP 65549 [TCP Out-Of-Order] 46988 → 7001 [ACK] Seq=4211997131 Ack=1 Win=65536 Len=65483 TSval=2693245610 TSecr=2693245610
190116 1.093457 127.0.0.1 → 127.0.0.1 TCP 65549 [TCP Out-Of-Order] 46988 → 7001 [ACK] Seq=4212062614 Ack=1 Win=65536 Len=65483 TSval=2693245610 TSecr=2693245610
190117 1.093457 127.0.0.1 → 127.0.0.1 TCP 1762 [TCP Out-Of-Order] 46988 → 7001 [PSH, ACK] Seq=4212128097 Ack=1 Win=65536 Len=1696 TSval=2693245610 TSecr=2693245610
190138 1.093547 127.0.0.1 → 127.0.0.1 TCP 1762 [TCP Out-Of-Order] 46988 → 7001 [PSH, ACK] Seq=4212128097 Ack=1 Win=65536 Len=1696 TSval=2693245610 TSecr=2693245610
[1]+ Done sudo tcpdump -s78 -wt.tcpdump -ilo port 7001
--2020-02-25_11:27:17--