Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl TCP、HTTP和多线程最佳点_Perl_Multithreading_Http_Tcp_Network Programming - Fatal编程技术网

Perl TCP、HTTP和多线程最佳点

Perl TCP、HTTP和多线程最佳点,perl,multithreading,http,tcp,network-programming,Perl,Multithreading,Http,Tcp,Network Programming,我试图了解我得到的性能数据以及如何确定最佳线程数。 有关我的结果,请参见本文底部 我用perl编写了一个实验性的多线程web客户端,它下载一个页面,获取每个图像标记的源代码,然后下载图像——丢弃数据 它使用非阻塞连接,每个文件的初始超时为10秒,每次超时后加倍,然后重试。它还缓存IP地址,因此每个线程只需执行一次DNS查找 通过与的2.5Mbit连接,在1316个文件中下载的数据总量为2271122字节。缩略图像由一家声称专门为高带宽应用提供低延迟的公司托管 墙时间为: 1个线程需要4:48--

我试图了解我得到的性能数据以及如何确定最佳线程数。

有关我的结果,请参见本文底部

我用perl编写了一个实验性的多线程web客户端,它下载一个页面,获取每个图像标记的源代码,然后下载图像——丢弃数据

它使用非阻塞连接,每个文件的初始超时为10秒,每次超时后加倍,然后重试。它还缓存IP地址,因此每个线程只需执行一次DNS查找

通过与的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
平均rtt 100 ms(通过ping测量)
平均cli cpu/img 1毫秒

最快的平均下载速度是5个线程,总速度约为15KB/秒

实际上,服务器的延迟似乎很低,因为获取每个映像只需218毫秒,这意味着服务器处理每个请求平均只需18毫秒:

0 cli发送syn
50 srv RCV同步
50 srv发送syn+ack
100 cli连接已建立/cli发送get
150 srv recv的获取
168 srv读取文件、发送数据、调用关闭
218 cli recv HTTP头+两段中的完整文件MSS==1448

我可以看到,每个文件的平均下载速度很低,因为连接设置的文件大小很小,每个文件的成本相对较高

我不明白的是,为什么除了两个线程之外,我几乎看不到任何性能改进。服务器似乎足够快,但已经开始在5个线程上超时连接

超时似乎是在大约900-1000个成功连接之后开始的,不管是5个线程还是50个线程,我认为这可能是服务器上的某种限制阈值,但我预计10个线程仍然比2个线程快得多

我是不是遗漏了什么

编辑-1

为了便于比较,我安装了DownThemAll Firefox扩展,并使用它下载了图像。我将其设置为4个同时连接,超时时间为10秒。DTM下载所有文件并将其写入磁盘大约需要3分钟,并且在大约900次连接后,DTM也开始出现超时

我将运行tcpdump,尝试更好地了解tcp协议级别的情况

我还清除了Firefox的缓存并点击了重新加载。40秒重新加载页面和所有图像。这似乎太快了——也许Firefox将它们保存在一个未清除的内存缓存中?所以我打开了Opera,也花了大约40秒。我认为它们的速度要快得多,因为它们必须使用HTTP/1.1管道

答案是

因此,在经过一点测试和编写代码以通过管道重用套接字之后,我发现了一些有趣的信息

当在5个线程上运行时,非流水线版本将在77秒内检索到前1026个图像,但检索其余290个图像还需要65秒。这几乎证实了我的客户端被
synflood
事件击中的理论,该事件导致服务器在短时间内停止响应我的连接尝试。然而,这只是问题的一部分,因为77秒对于5个线程来说仍然非常慢,无法获得1026张图像;如果删除
synflood
问题,检索所有文件仍需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缓冲区大小 以及正在下载的图像文件的大小

除上述情况外,平均文件大小还会影响每个连接的最大值 传输速率。每次发出GET请求时,都会在 您的输送管的尺寸为连接RTT的尺寸。例如,如果 您的最大可能传输速率(recv buff size/RTT)为2.5Mbit,并且 您的RTT是100ms,那么每个GET请求在您的RTT中产生最小32kB的间隔 管对于平均大小为320kB的大型图像,这相当于10%的开销 每个文件,有效地将可用带宽减少到2.25Mbit。然而, 对于平均大小为3.2kB的小文件,开销会增加到1000%,并且 可用带宽降低到232 kbit/秒-约29kB

要找到最佳线程数:

间隙大小=MPTR*RTT
MPTR/(MPTR/间隙大小+平均文件大小)*平均文件大小)

对于我上面的场景,这给了我11个线程的最佳线程数,这非常接近我的真实结果

如果实际连接速度低于理论MPTR,则 应改为在计算中使用。

请更正此总数