如何最大化http.sys文件上传性能

时间:2010-05-05 23:10:07

标签: c# .net performance http.sys

我正在构建一个工具,可以从一台服务器向另一台服务器传输非常大的流数据集(可能在单个流中的数量级为TB,通常为几十千兆字节)。该工具的客户端部分将从源磁盘读取块,并通过网络发送它们。服务器端将从网络中读取这些块并将其写入服务器磁盘上的文件。

现在我正在尝试决定使用哪种传输方式。选项是原始TCP和HTTP。

我真的,真的希望能够使用HTTP。 HttpListener(或WCF,如果我想去那条路线)可以很容易地插入HTTP Server API(http.sys),我可以免费获得身份验证和SSL之类的东西。现在的问题是表现。

我编写了一个简单的测试工具,使用BeginWrite / EndWrite异步I / O习惯用于在服务器端使用异步BeginRead / EndRead发送128K块空字节。我已修改此测试工具,因此我可以通过HttpWebRequest / HttpListener进行HTTP PUT操作,或使用TcpClient / TcpListener进行普通旧套接字写操作。要排除网卡或网络路径问题,客户端和服务器都在一台计算机上,并通过localhost进行通信。

在我的12核Windows 2008 R2测试服务器上,此测试工具的TCP版本可以以450MB / s的速度推送字节,并且CPU使用率最低。在同一个盒子上,测试工具的HTTP版本在130MB / s和200MB / s之间运行,具体取决于我如何调整它。

在这两种情况下,CPU使用率都很低,并且CPU使用的绝大部分是内核时间,因此我非常确定我使用C#和.NET运行时不是瓶颈。该盒子有两个6核Xeon X5650处理器,24GB单排DDR3内存,我自己专门用于自己的性能测试。

我已经了解了ServicePointManager.MaxServicePointIdleTimeServicePointManager.DefaultConnectionLimitServicePointManager.Expect100ContinueHttpWebRequest.AllowWriteStreamBuffering等HTTP客户端调整问题。

有没有人对如何使HTTP.sys性能超过200MB / s有任何想法?有没有人看到它在任何环境下表现都很好?

更新

以下是TcpListener vs HttpListener所见的表现的更多细节:

首先,我写了一个TcpClient / TcpListener测试。在我的测试盒上能够推动450MB / s。

然后使用反射器我想出了如何获取HttpWebRequest底层的原始Socket对象,并修改了我的HTTP客户端测试以使用它。仍然没有快乐;差不多200MB / s。

我目前的理论是,http.sys针对典型的IIS用例进行了优化,这是一个很多并发的小请求,以及大量并发和可能很大的响应。我假设为了实现这种优化,MSFT必须以牺牲我正在努力实现的目标为代价,这在一个非常大的请求上具有非常高的吞吐量,响应非常小。

为了它的价值,我还尝试了多达32个并发HTTP PUT操作,看它是否可以扩展,但仍然没有快乐;大约200MB / s。

有趣的是,在我的开发工作站上,运行64位Windows 7的四核Xeon Precision T7400,我的TcpClient实现大约200MB / s,HTTP版本也大约200MB / s。一旦我将它带到运行Server 2008 R2的高端服务器级机器上,TcpClient代码就会达到450MB / s,而HTTP.sys代码则保持在200左右。

此时我遗憾地得出结论,HTTP.sys不是我需要完成的工作的正确工具,并且必须继续使用我们一直使用的手动插槽协议。

2 个答案:

答案 0 :(得分:2)

除了Tech Note之外,我看不出太多的兴趣。使用MaxBytesPerSend

可能值得一提

答案 1 :(得分:0)

如果您要通过LAN发送文件,那么UDP是可行的方法,因为在这种情况下TCP的开销是浪费。 TCP提供速率限制以避免丢失太多数据包,而使用UDP时,应用程序必须自行对其进行排序。 NFS会完成这项工作,难道不是你被Windows困住了;但我敢肯定必须有现成的UDP东西。还可以使用工具“iperf”(可在Linux上获得,可能还有windows)来对网络链接进行基准测试,而不管协议如何。有些网卡是普通垃圾,过于依赖CPU,这会将你的速度限制在200mbit。你想要一个合适的网卡和自己的处理器(不知道准确的条款)。