昨天我家里有了一条崭新闪亮的 VDSL2 连接!它的规格为 100Mbit/10Mbit,似乎非常接近标准。
现在,我有一个 Debian squeeze linux 机器,用作家庭 NAS 和路由器。它运行 shorewall,启用了 NAT 和 tc。我还有一个 OSX 工作站,通过交换机连接到上述 linux 路由器:
OSX工作站<->转变<->Debian 路由器<->VDSL2 调制解调器<->互联网<->服务器
我针对互联网上的快速服务器进行了测试:
在 Linux 路由器上,TCP:
$ iperf -c server -p 3333
------------------------------------------------------------
Client connecting to server, TCP port 3333
TCP window size: 23.5 KByte (default)
------------------------------------------------------------
[ 3] local xxx.yyy.bbb.ccc port 41982 connected with xxx.yyy.bbb.ccc port 3333
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 2.89 MBytes 2.42 Mbits/sec
问题就出在上面。上行链路应该是~10Mbit,而不是 2.4Mbit。下面,你可以看到 UDP 工作正常。
在 Linux 路由器上,UDP:
$ iperf -u -c server -p 60008 -b 9M
------------------------------------------------------------
Client connecting to server, UDP port 60008
Sending 1470 byte datagrams
UDP buffer size: 1.00 MByte (default)
------------------------------------------------------------
[ 3] local xxx.yyy.bbb.ccc port 56484 connected with xxx.yyy.bbb.ccc port 60008
[ ID] Interval Transfer Bandwidth
[ 3] 0.0-10.0 sec 10.7 MBytes 9.00 Mbits/sec
[ 3] Sent 7658 datagrams
[ 3] Server Report:
[ 3] 0.0-10.0 sec 10.7 MBytes 9.00 Mbits/sec 0.251 ms 0/ 7657 (0%)
[ 3] 0.0-10.0 sec 1 datagrams received out-of-order
在 OSX Workstation 上(NAT 后面)TCP:
$ iperf -c server -p 3333
------------------------------------------------------------
Client connecting to server, TCP port 3333
TCP window size: 65.0 KByte (default)
------------------------------------------------------------
[ 5] local 192.168.9.141 port 54388 connected with xxx.yyy.bbb.ccc port 3333
[ ID] Interval Transfer Bandwidth
[ 5] 0.0-10.0 sec 13.2 MBytes 11.1 Mbits/sec
Linux 路由器后面的 OSX 似乎不受 Linux 路由器问题的影响。怎么会这样?UDP 也运行正常。
在 OSX Workstation 上(NAT 后面)UDP:
$ iperf -u -c server -p 60008 -b 9M
------------------------------------------------------------
Client connecting to server, UDP port 60008
Sending 1470 byte datagrams
UDP buffer size: 9.00 KByte (default)
------------------------------------------------------------
[ 5] local 192.168.9.141 port 64588 connected with xxx.yyy.bbb.ccc port 60008
[ ID] Interval Transfer Bandwidth
[ 5] 0.0-10.0 sec 10.7 MBytes 9.00 Mbits/sec
[ 5] Sent 7658 datagrams
[ 5] Server Report:
[ ID] Interval Transfer Bandwidth Jitter Lost/Total Datagrams
[ 5] 0.0-10.0 sec 10.7 MBytes 9.00 Mbits/sec 0.133 ms 0/ 7658 (0%)
如您所见,Linux 机器的出站 TCP 速度卡在 2.5Mbit/s。UDP 工作正常,路由器后面的工作站工作正常。
为了简化情况,我将 Shorewall TC 修改为非常基本的级别。我还尝试从 Shorewall 完全关闭 TC,但没有任何效果。:
tcdevices:
#INTERFACE IN-BANDWITH OUT-BANDWIDTH
eth0 - 12000kbit
tcclasses:
#INTERFACE MARK RATE CEIL PRIORITY OPTIONS
eth0 1 full full 1 default
tcrules:
#MARK SOURCE DEST PROTO PORT(S) CLIENT USER
1:F 0.0.0.0/0 0.0.0.0/0 icmp echo-request
1:F 0.0.0.0/0 0.0.0.0/0 icmp echo-reply
你知道问题可能出在哪里吗?我在 Debian 上运行的唯一非默认的东西是来自反向移植的 3.2.0 内核。这台机器是一台功能强大的 Xeon 机器,拥有大量 RAM 和 Intel 网卡。所有测试都在很短的时间内完成,几乎没有其他网络流量。并重复多次。我可以从哪里开始调试?
答案1
我找到了解决问题的方法。我所要做的就是关闭网卡上的分段卸载:
ethtool -K eth0 gso off tso off
这帮我解决了这个问题。显然这很常见。
答案2
几点:
1.) TCP 可能需要一点时间才能达到全速 - 无论是在较长的流上找到合适的窗口大小,还是在较短的流上设置时间(即使用 TCP 进行握手时为 1.5 x RTT,而使用 UDP 则立即启动)。10 兆字节的数据量并不大。当您向 1G 标记推进时,您应该会看到 TCP 的平均速度有所提高。
2.) 即使完全优化,可靠性和性能之间也存在权衡。即使在完美的实验室条件下,TCP 也可能对微突发异常敏感。在 DSL 设置上运行(无论速度多快)都可能使流量暴露于不同数量的缓冲、序列化延迟等。同样,这往往会在较长的流量中达到平均水平。UDP(尤其是在性能基准测试中)将尽可能地传输,而不考虑数据包丢失、缓冲区溢出等。
因此,TCP 窗口化的想法是,如果它运行完美,那么我们就会达到这样一种情况:在传输过程中,流量达到最优,开销(即确认、TCP 报头等)百分比最小。实际上,传输中的流量应该允许恒定的带宽 - 即使确认正在流动。TCP 的性能将逐渐接近完全开放的数据传输。
相比之下,UDP 是一种广泛开放的数据传输……
现在 - 不同平台之间的性能差异将取决于 TCP 的具体实现以及系统本身如何确定 I/O 和协议处理的优先级。可能会有一两个调整使这两个值达到更好的平衡。不过,样本的大小仍然是一个问题。测试越多,规模越大,结果就越准确。