混合以太网速度的Windows 2008服务器 – 从共享下载慢,但快速普通的TCP

我有一个Windows Server 2008 R2 x64服​​务器是AD控制器和文件服务器。 我遇到了一个问题,即Windows XP客户端从共享中下载文件的速度非常慢(低于10Mbps,实际低于10兆比特每秒)。

服务器使用1Gbps Nvidia NForce卡连接到1Gbps交换机,客户端使用100Mbps内置卡连接。

当我从CentOS Linux 5.5 Live-USB启动客户端电脑并使用smbclient进行下载时,也可以看到这种慢速下载。 但是,使用1Gbps链接连接的Linux服务器上的Samba共享下载速度也很快。

奇怪的是,我创build了一对程序(下面附带),用于testingC#中纯TCP的吞吐量,它们的性能如预期的那样高达89Mbps。

我已经禁用客户端上的防火墙,我在客户端上使用dot_nc_l 21000 > NIL ,在Windows服务器上使用dot_nc [client_ip] < 100m.dat 。 而我约9秒,从共享复制相同的100MB文件需要2分钟。

如何消除这一点?


在Linux客户端上使用wireshark生成的一些图片:

将从Windows 2008 CIFS文件服务器连接到1Gbps NIC的100MB文件下载到使用smbclient连接到100Mbps NIC的Centos 5 Linux客户端: 看起来像鲨鱼牙齿的图形

将从1Gbps NIC连接的Samba上的Fedora Linux CIFS文件服务器的100MB文件下载到Centos 5 Linux客户端,连接100mbbps的smbclient网卡(与上述规模相同): 看起来像地震仪的图不在地震中


以下是这些程序(链接使用mono的gmcs编译,需要.NET2):

dot_nc.cs

 using System; using System.IO; using System.Diagnostics; using System.Net.Sockets; public class dot_nc { public static void Main(string[] args) { string hostname = args[0]; int port = int.Parse(args[1]); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); TcpClient client = new TcpClient(hostname, port); stopwatch.Stop(); Console.WriteLine("Connection: {0}ms", stopwatch.ElapsedMilliseconds); stopwatch.Reset(); stopwatch.Start(); byte[] buffer = new byte[4096]; { Stream stdin = Console.OpenStandardInput(); NetworkStream netout = client.GetStream(); while ( true ) { int bytesread = stdin.Read(buffer, 0, buffer.Length); if ( bytesread <= 0 ) { break; } netout.Write(buffer, 0, bytesread); } } stopwatch.Stop(); Console.WriteLine("Sending: {0}ms", stopwatch.ElapsedMilliseconds); client.Close(); } } 

dot_nc_l.cs

 using System; using System.IO; using System.Diagnostics; using System.Net; using System.Net.Sockets; public class dot_nc { public static void Main(string[] args) { int port = int.Parse(args[0]); TcpListener server = new TcpListener(IPAddress.Any, port); server.Start(); TcpClient client = server.AcceptTcpClient(); NetworkStream netin = client.GetStream(); byte[] buffer = new byte[4096]; Stream stdout = Console.OpenStandardOutput(); int processed_bytes = 0; int processed_chunks = 0; while ( true ) { int bytesread = netin.Read(buffer, 0, buffer.Length); if ( bytesread <= 0 ) { break; } stdout.Write(buffer, 0, bytesread); processed_bytes += bytesread; processed_chunks++; } netin.Close(); client.Close(); server.Stop(); Console.Error.WriteLine( "Received: {0} chunks of data of {1} average size", processed_chunks, processed_bytes/processed_chunks ); } } 

问题是由于:

  • 在廉价的千兆交换机中太小的数据包缓冲区;
  • Windows Server 2008文件服务中使用的拥塞避免algorithm不足;
  • 禁用networking适配器中的stream量控制(默认情况下已禁用)。

由于stream量控制被禁用,Windows正在使用1Gbps连接在一批中将数据包发送到窗口大小。 由于100Mbps客户端接收数据包的速度要慢得多,几乎所有窗口大小的数据都需要通过交换机进行caching。 由于这种便宜的交换机具有非常小的缓冲区(缓冲区大小甚至没有在规范中说明,但是每个端口必须小于64kB,因为即使禁用窗口缩放也没有帮助),所以必须丢弃多余的分组。 数据包丢失导致graphics上出现约0.25秒的延迟。 但是文件服务中使用的拥塞避免algorithm并没有减lessTCP窗口的大小,所以下一批数据包不会减less – 拥塞连接一次又一次导致拥塞崩溃 。

标准的TCP连接(不是文件服务)必须使用不同的拥塞控制algorithm,并且不会重复拥塞。 我想对待文件服务特别是由Windows TCP堆栈帮助基准例如桑巴。

所以解决scheme是:

  • 在networking适配器属性中启用stream量控制。 这不是一个理想的解决scheme,因为任何文件服务转移到100Mbps的客户端也会减慢并发转移到1Gbps的客户端速度低于100Mbps。

  • 或者将100Mbps客户端连接到具有更大缓冲区的企业级交换机。 这是我用过的解决scheme。 我有一个10年的“3Com SuperStack 3 3300 SM”交换机,带有一个1000Base-SX光纤千兆以太网MT-RJ端口。 我购买了带有LC端口的Cisco 1000BASE-SX迷你Gbic模块(MGBSX1) ,用于我的Linksys千兆交换机和LC / MT-RJ多模光纤跳线(两者都价值约150美元),并将所有100Mbps客户端连接到此3COM交换机。 我也启用stream量控制,但不应该导致连接没有100Mbps的客户端变慢。

感谢SpacemanSpiff ,他的评论帮助解决了这个问题。

Windows服务器是否启用SMB签名 ? SMB签名会增加速度,并且在域控制器上默认启用 。

可能是100Mbps卡/开关? 您提到当1Gbps时,同一个客户端正常工作。

感觉像一个较低级别的networking问题。 我的猜测:

  • 双面不匹配问题。 这肯定会使性能下降很多。 在Linux一侧,使用ethtool命令来validation您的协商在100 Mbps /全双工。 如果你的卡以100 / Half进行协商,并且交换机认为连接是100 / Full,那么将会有所有types的问题。 你可能想试试强制100 / Full而不是自动协商速度(记住你必须在交换机和系统上强制100 / Full)
  • 它也可能是客户端的网卡或交换机上的缓冲区问题。 我见过网卡驱动程序没有分配足够的缓冲区空间,并导致速度问题。 我想象在交换机上可能会发生同样types的问题。 更难以诊断,其他然后交换设备。

您可以尝试通过esetutil进行复制(如果您有交换服务器)

检查此: http : //blogs.technet.com/b/askperf/archive/2007/05/08/slow-large-file-copy-issues.aspx

这可能是一个testing,如果你从客户端复制到服务器的大文件,反之亦然testing如果esetutil获得更好的性能。

我也有类似的问题与Windows 2008和Linux服务器与选项名为NetDMA(最后一节)。 这解决了我的问题(是一个Broadcomnetworking适配器与团队)


如何启用和禁用Windows Server 2008中的NetDMA要启用或禁用NetDMA,请按照下列步骤操作:单击开始,单击运行,键入regedit,然后单击确定。 find以下registry子项,然后单击它:HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services \ Tcpip \ Parameters双击EnableTCPAregistry项。 注意如果此registry项不存在,请右键单击Parameters,指向新build,单击DWORD值,键入EnableTCPA,然后按Enter。 要启用NetDMA,请在“数值数据”框中键入1,然后单击“确定”。 要禁用NetDMA,请在“数值数据”框中键入0,然后单击“确定”。 如果EnableTCPAregistry项不存在,请启用NetDMAfunction。 本文讨论的第三方产品是由独立于Microsoft的公司制造。 对于这些产品的性能或可靠性,Microsoft不作任何暗示或其他forms的保证


从支持Microsoft KB 951037

检查您的服务器/客户端的BIOS是否有“CPU C状态”参数(可能在节电类别内)。 如果存在,请尝试将该参数设置为禁用。