我有一个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 ); } }
问题是由于:
由于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问题。 我的猜测:
您可以尝试通过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状态”参数(可能在节电类别内)。 如果存在,请尝试将该参数设置为禁用。