我试图了解我得到的性能数据以及如何确定最佳线程数。
我的结果见这篇文章的底部
我用Perl编写了一个实验性的多线程Web客户机,它下载一个页面,获取每个图像标记的源代码并下载图像—丢弃数据。
它使用非阻塞连接,每个文件的初始超时为10秒,每次超时后加倍,然后重试。它还缓存IP地址,因此每个线程只需进行一次DNS查找。
通过2.5Mbit连接,从1316个文件中下载的数据总量为2271122字节
http://hubblesite.org/gallery/album/entire/npp/all/hires/true/
. 这些缩略图由一家公司托管,该公司声称专门从事高带宽应用程序的低延迟。
墙壁时间是:
一个线程占用4:48--0个超时
2个线程占用2:38--0个超时
5个线程占用2:22--20个超时
10个线程占用2:27--40个超时
50个线程占用2:27--170个超时
在最坏的情况下(50个线程),客户端占用的CPU时间少于2秒。
平均文件大小1.7k
平均rtt 100 ms(由ping测量)
平均cli cpu/img 1 ms
最快的平均下载速度是5个线程,总速度约为15kb/s。
服务器实际上似乎具有相当低的延迟,因为获取每个图像只需218毫秒,这意味着服务器处理每个请求平均只需18毫秒:
0 cli发送syn
50 SRV RCV同步
50 srv发送syn+ack
100个cli conn已建立/cli发送get
150 SRV接收
168srv读取文件,发送数据,调用关闭
218 cli recv http headers+两段完整文件mss==1448
我可以看到,每个文件的平均下载速度很低,因为连接设置的文件大小较小,每个文件的成本相对较高。
我不明白的是,除了两个线程之外,我几乎看不到性能的改善。服务器似乎足够快,但已经开始在5个线程上超时连接。
无论是5个线程还是50个线程,超时似乎都是在900-1000个成功连接之后开始的,我认为这可能是服务器上的某种限制阈值,但我预计10个线程仍将明显快于2个线程。
我是不是丢了什么东西?
编辑1
为了便于比较,我安装了downthemall firefox扩展并使用它下载了图像。我将其设置为4个同时连接,超时10秒。DTM花了大约3分钟的时间下载所有文件并将其写入磁盘,而且在大约900个连接之后,DTM也开始出现超时。
我将运行tcpdump来尝试更好地了解tcp协议级别的情况。
我还清除了firefox的缓存并点击reload。40秒重新加载页面和所有图像。这看起来太快了——也许火狐把它们放在了一个没有清除的内存缓存中?所以我打开了歌剧,也花了大约40秒。我认为它们的速度更快,因为它们必须使用http/1.1管道?
答案是!???
因此,在通过管道测试和编写代码以重用套接字之后,我发现了一些有趣的信息。
当以5个线程运行时,非流水线版本在77秒内检索前1026个映像,但检索其余290个映像需要65秒。这几乎证实了
MattH's
关于我的当事人被
SYN FLOOD
导致服务器在短时间内停止响应我的连接尝试的事件。但是,这只是问题的一部分,因为77秒对于5个线程获取1026个图像仍然非常慢;如果删除
合成洪水
问题检索所有文件仍需要大约99秒。所以基于一点研究和一些
tcpdump
问题的另一部分似乎是延迟和连接设置开销。
这里我们回到寻找“最佳点”或最佳线程数的问题。我修改了客户端以实现http/1.1管道,发现在这种情况下,最佳线程数在15到20之间。例如:
1线程占用2:37--0个超时
2个线程占用1:22--0个超时
5个线程占用0:34--0个超时
10个线程占用0:20--0个超时
11个线程占用0:19--0个超时
15个线程占用0:16--0个超时
有四个因素
影响;延迟/rtt、最大端到端带宽、recv缓冲区大小
以及正在下载的图像文件的大小。
See this site for a
discussion on how receive buffer size and RTT latency affect available
bandwidth
.
除上述之外,平均文件大小还影响每个连接的最大值
传输速率。每次发出get请求时,都会在
你的传输管是连接RTT的尺寸。例如,如果
最大可能传输速率(recv buff size/rtt)为2.5mbit,并且
你的rtt是100ms,那么每个get请求在你的
管子。对于平均大小为320kb的大型图像,这相当于10%的开销
每个文件,有效地将可用带宽减少到2.25mbit。然而,
对于3.2kb的小平均文件大小,开销会跳到1000%,并且
可用带宽减少到232 kbit/秒-大约29 kb。
因此,要找到最佳线程数:
间隙尺寸=MPTR*RTT
mptr/(mptr/gap size+avg file size)*平均文件大小)
对于我上面的场景,这给了我11个线程的最佳线程数,这与我的实际结果非常接近。
如果实际连接速度低于理论mptr,则
应改为在计算中使用。