调整窗口以适应高延迟/高带宽 TCP 传输

调整窗口以适应高延迟/高带宽 TCP 传输

如何才能加快芝加哥和伦敦之间 100 mbps 链路上的 Windows 7 tcp 文件传输速度?

现在,我正在两个 sftp 会话中传输两个 4GB 文件。每个文件传输的速率为 500 KB/s(4 Mbits/sec)。(B == 字节,b == 位,自然如此)。这相当慢,因为 iperf 测试显示单个 TCP 流的速率为 16.8 Mbits/sec。也就是 2 MB/sec。

启动第二个 sftp 会话不会对第一个会话的速度产生丝毫影响。这对我来说很有意义,因为我注意到我的 iperf 测试受限于 TCP - 每个连接为 16 Mbps,这为更多连接留出了空间。我能够通过运行许多并行连接使 iperf 饱和我的线路,并且带宽呈线性增加。也就是说,通过 5 个并行连接,我实现了大约 5x16 == 80 Mbps 的带宽。

我注意到使用 sftp 的本地文件传输速度约为 30 MB/s... 相当不错。因此,我认为 SSH 通道加密不是瓶颈。

我已经评论过通过高速、高延迟的 WAN 链路传输单个大文件的最佳方法是什么?以及其他服务器故障问题,并且有很多有趣的工具,但我正在寻找一种方法来调整 Windows 的 TCP 堆栈,以确保我至少获得完整的 2 MB......甚至更多,因为 iPerf 测试是在未调整的机器上进行的。

我还注意到,当我将文件从我的芝加哥文件服务器拖放到伦敦机器上时,传输速度似乎相当快(从传输过程中的详细信息可以看出),但几分钟后,速度就急剧下降到 10 Kbps。这很奇怪。

我的延迟稳定在 88 毫秒左右,所以我认为网络基础设施很好。我们有一条专用线路;这不是互联网上的 VPN 或类似的东西。

========

我有一台 Linux VM,从网络角度来说,它与我的 Windows 桌面“接近”。也就是说,它们位于不同的子网中,但两台机器都接入交换机,而这两台机器都接入另一台通往伦敦的交换机。现在,我正在运行从 Linux 到伦敦的 sftp,它以 8 MB/s 的速度运行,而我的桌面则以 500 KB/s 的速度运行。

======== 好的,我将 Linux 笔记本电脑与台式机放在完全相同的交换机上。此时台式机以 500 KB/s 的速度执行 sftp,而 Linux 笔记本电脑则以 7.6 MB/s 的速度发送 4G 文件。当然,是发送到伦敦的同一台服务器。

======== 另一项测试:我使用的是 VanDyke Corp 的 SecureFX。我的 PC 上也有 Cygwin,我刚刚在那里使用了 CLI sftp 命令。我的吞吐量增加了五倍……我现在的吞吐量是 2.5 MB/s,而不是 500k!:-\ 这与我的 iPerf 结果 16 Mbps 相当。我本来会对此感到满意……尽管现在我注意到我的笔记本电脑的速度是它的三倍。

======== 另一项测试:在我的伦敦机器上,我开始将 Windows 资源管理器文件从我在芝加哥的文件服务器复制到本地安装的下载文件夹(即内部硬盘上)。吞吐量稳定在 5.49 MB/s,持续了 12 分钟左右。这对我来说已经足够好了!同样,通过 SecureCRT 复制的速度非常慢 - 稳定在 500 KB/s。

我唯一能得出的结论是,尽管 TCP 调整可能会有所帮助,但您使用的应用程序可能会产生很大的不同!此外,我不知道为什么我的文件复制前几天表现得如此奇怪。如果再次发生这种情况,我会尝试调试。

感谢您的建议和回复。

======================

好的,我关注了 Todd Wilcox 的链接并弄清楚了一些事情:

  • 首先,根据微软的说法,https://technet.microsoft.com/en-us/library/cc957546.aspx?f=255&MSPPError=-2147217396, “TCP 使用接收窗口...对于以太网网络,此条目的默认值为 0x4470(17,520,或 12 个段,每个段 1,460 字节)”嗯,我有一个延迟为 80 毫秒的 WAN,所以这个太小了。
  • 我已将注册表中的 GlobalMaxTcpWindowSize 和 TcpWindowSize(后者在我的适配器上)都设置为 1 MiB,然后转到命令行并将netsh接收窗口自动调整级别从正常更改为禁用。我的网络传输速度没有改变,所以我重新启动了我的计算机并再次从我的桌面执行 sftp 到伦敦服务器。
  • 吞吐量骤降到 700 KB/s。不用说,我把所有设置都恢复了,然后再次重启。现在我的吞吐量又回到了 2.1 MB/s。
  • 在 sftp 期间,Wireshark 显示了奇怪的锯齿状 TCP 窗口缩放模式,从大约 64000 字节变为 62000 字节,然后又恢复原状。该循环大约需要 35 秒。
  • 假设我的平均窗口大小为 63000 字节。因此,我的 Bps 吞吐量应该是(从http://bradhedlund.com/2008/12/19/how-to-calculate-tcp-throughput-for-long-distance-links/)、窗口大小(字节)/延迟(秒)== 700 KB/s。奇怪的是我得到了 2.1 MB/s...这比理论值要高!我敢肯定中间没有 Wan 加速器,也没有比 Cisco 4948 更复杂的东西。也许 Wireshark 的窗口缩放图与窗口大小不一样,我不知道,但谷歌搜索告诉我,那是我可以找到 TCP 窗口大小的地方。
  • 事情不太对劲。虽然我确实发现我的小动作确实把事情搞砸了,但我不知道如何确切地说出我的 TCP 窗口大小。此外,经常被引用的 Brad Hedlund 页面给出了一些计算结果,但这些计算结果并没有反映在我的经验中。
  • 最后,这是我学到的最重要的一课:我想我会放手不管。如果我们发现需要更好的吞吐量,也许我会推荐一个 WAN 加速器。但由于我们要跨越半个地球,我们不应该指望单个 TCP 连接就能提供惊人的带宽。

答案1

计算最佳 TCP 窗口大小的公式(来源):

每秒带宽(位数)* 往返延迟(秒)= TCP 窗口大小(位数)/8 = TCP 窗口大小(字节)

就你的情况而言:100 000 000 * .088 = 8 800 000 位或 1 100 000 字节

这可以在 Windows 注册表中的 TcpWindowSize 项中配置,有效范围是 0-0x3FFFFFFF(十进制为 1 073 741 823),因此该数字在有效范围内。

默认值为下列值中的最小值(注意:“仅当连接到支持 RFC 1323 窗口缩放的其他系统时,才能实现大于 64 KB 的值“):

  • 0xFFFF
  • GlobalMaxTcpWindowSize(另一个注册表参数)
  • 取 MSS (最大段大小) 四倍中的较大者
  • 16384 四舍五入为 MSS 的偶数倍

该堆栈还会根据媒体速度进行自我调整:

  • 低于 1 Mbps:8 KB
  • 1 Mbps – 100 Mbps:17 KB
  • 大于 100 Mbps:64 KB

来源(此链接现在基本已失效,但有一点恢复,但只有奇迹才能使其恢复)


另请参阅:http://bradhedlund.com/2008/12/19/how-to-calculate-tcp-throughput-for-long-distance-links/

和:https://technet.microsoft.com/en-us/library/cc938219.aspx

相关内容