Rob*_*nes 6 perl multithreading network-programming tcp http
我试图了解我得到的性能数字以及如何确定最佳线程数.
有关我的结果,请参阅本文的底部
我在perl中编写了一个实验性多线程Web客户端,用于下载页面,抓取每个图像标记的源并下载图像 - 丢弃数据.
它使用非阻塞连接,每个文件的初始超时为10秒,每次超时后重复一次并重试.它还缓存IP地址,因此每个线程只需执行一次DNS查询.
通过http://hubblesite.org/gallery/album/entire/npp/all/hires/true/的 2.5Mbit连接,1316个文件中下载的数据总量为2271122个字节.缩略图由一家公司托管,该公司声称专门为高带宽应用提供低延迟.
挂壁时间是:
1线程需要4:48 - 0超时
2线程需要2:38 - 0超时
5线程需要2:22 - 20次超时
10线程需要2:27 - 40次超时
50线程需要2:27 - 170次超时
在最坏的情况下(50个线程),客户端消耗的CPU时间少于2秒.
平均文件大小1.7k
avg rtt 100 ms(通过ping测量)
avg cli cpu/img 1 ms
最快的平均下载速度是5个线程,总体上大约15 KB /秒.
服务器实际上确实具有相当低的延迟,因为每个映像只需要218毫秒,这意味着服务器平均只需要18毫秒来处理每个请求:
0 cli发送syn
50 srv rcvs syn
50 srv发送syn + ack
100 cli conn建立/ cli发送获取
150 srv recv获取
168 srv读取文件,发送数据,调用关闭
218 cli recv HTTP头文件+ 2个段中的完整文件MSS == 1448
我可以看到每个文件的平均下载速度很低,因为文件很小,连接设置的每个文件的成本相对较高.
我不明白的是为什么我看到超过2个线程的性能几乎没有改善.服务器似乎足够快,但已经开始超时连接5个线程.
超时似乎是在大约900到1000个成功连接之后开始的,无论它是5个还是50个线程,我认为这可能是服务器上的某种限制阈值,但我预计10个线程仍然会比2快得多.
我在这里错过了什么吗?
编辑-1
为了比较,我安装了DownThemAll Firefox扩展并使用它下载了图像.我将它设置为4个同时连接,10秒超时.DTM花了大约3分钟来下载所有文件并将它们写入磁盘,并且在大约900个连接之后它也开始经历超时.
我将运行tcpdump来尝试更好地了解tcp协议级别的情况.
我还清除了Firefox的缓存并重新加载.40秒重新加载页面和所有图像.这似乎太快了 - 也许Firefox将它们保存在一个未清除的内存缓存中?所以我打开了Opera,它也花了大约40秒.我认为他们的速度要快得多,因为他们必须使用HTTP/1.1流水线技术?
而答案是!??
因此,经过一些测试和编写代码以通过流水线重用套接字后,我发现了一些有趣的信息.
当以5个线程运行时,非流水线版本在77秒内检索前1026个图像,但还需要65秒来检索剩余的290个图像.这几乎证实了MattH关于我的客户端被一个SYN FLOOD事件击中的理论,导致服务器在短时间内停止响应我的连接尝试.然而,这只是问题的一部分,因为5个线程获得1026个图像的77秒仍然很慢; 如果你删除了SYN FLOOD问题,它仍然需要大约99秒来检索所有文件.因此,基于一些研究,有些tcpdump人似乎问题的另一部分是延迟和连接设置开销.
这是我们回到找到"甜点"或最佳线程数的问题.我修改了客户端以实现HTTP/1.1 Pipelining,并发现在这种情况下最佳线程数在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缓冲区大小和正在下载的映像文件的大小. 有关接收缓冲区大小和RTT延迟如何影响可用带宽的讨论,请参阅此站点.
除上述内容外,平均文件大小会影响每个连接传输速率的最大值.每次发出GET请求时,都会在传输管道中创建一个空间隙,该间隙是连接RTT的大小.例如,如果您的最大可能传输速率(recv buff size/RTT)为2.5Mbit且RTT为100ms,那么每个GET请求都会在管道中产生至少32kB的间隙.对于320kB的大平均图像大小,相当于每个文件10%的开销,有效地将可用带宽减少到2.25Mbit.但是,对于3.2kB的小平均文件大小,开销会跳跃到1000%,可用带宽会降低到232 kbit /秒 - 大约29kB.
所以要找到最佳线程数:
间隙大小= MPTR*RTT
MPTR /(MPTR /间隙大小+ AVG文件大小)*AVG文件大小)
对于我上面的场景,这给了我11个线程的最佳线程数,这非常接近我的真实世界结果.
如果实际连接速度低于理论MPTR,则应在计算中使用它.
请纠正我这个摘要是不正确的:
multi-threaded客户端将启动一个连接到服务器的线程,HTTP GET然后只发出一个该线程关闭的线程.我建议服务器通过Web服务器守护程序本身,服务器本地防火墙或最可能的专用防火墙对http连接进行速率限制.
您实际上是滥用Web服务而不是为多个请求重新使用HTTP连接,并且您遇到的超时是因为您SYN FLOOD被钳制.
Firefox和Opera可能使用4到8个连接来下载所有文件.
如果重新设计代码以重新使用连接,则应获得类似的性能.
| 归档时间: |
|
| 查看次数: |
1082 次 |
| 最近记录: |