有没有一种方法确定最佳线程数量?

6

我正在进行网络爬虫,并使用线程下载页面。

我的程序性能的第一个限制因素是带宽,我无法下载更多的页面。

第二个问题是我所关心的。我正在使用线程同时下载多个页面,但是随着我创建的线程越来越多,处理器共享的负担也越来越大。是否有某些指标/方法/测试类可以确定理想的线程数量或者在达到一定数量后,性能不会再改变或者下降?


2
如果您的应用程序是CPU密集型的,那么线程数就应该接近于机器上的CPU数量。然而,像网络爬虫这样的I/O密集型程序经常会因为I/O阻塞而停顿,因此您可能可以配置更多线程。因此,我同意@pst的评论:运行测试,然后确定适合您环境的理想线程数。代码中没有真正好的方法来检测这一点。(但是,一旦了解了如何检查“当前平均”带宽,您可以编写自调节代码。) - Platinum Azure
4个回答

0
我们开发了一个多线程并行网络爬虫。基准测试吞吐量是获取此程序能否处理其工作的最佳方法。对于专用的Java服务器,每个核心一个线程是一个开始的基础,然后就涉及到I/O操作并进行更改。
在某些线程数后性能会下降。但这取决于您所爬网站的响应速度,使用的操作系统等。尝试寻找一个具有相对恒定响应时间的网站来进行您的第一次基准测试(像Google,不同服务)。
在访问速度较慢的网站上,更高数量的线程有助于补偿 I/O 阻塞。

整个程序完成并运行测试后,我会准备一个脚本。 - Renato Dinhani

0

请看看我在这个帖子中的回答

如何找到最优的线程数量?

您的示例可能会受到 CPU 绑定的影响,因此您需要一种方法来解决争用问题,以便能够找出在您的机器上使用的正确线程数并使它们保持繁忙。分析将有所帮助,但请记住,它将取决于核心数(以及已经提到的网络延迟等),因此在连接您的线程池大小时,请使用运行时获取核心数。

很抱歉没有快速的答案,恐怕需要进行测试、测量、调整和重复的过程!


0

理想的线程数应该接近于硬件提供的核心数(虚拟核心)。这是为了避免线程上下文切换和线程调度。如果您正在进行大量的IO操作并且有许多阻塞读取(您的线程在套接字读取上被阻塞),建议您重新设计代码以使用非阻塞IO API。通常,这将涉及一个“选择器”线程,它将监视成千上万个套接字的活动和少量的工作线程来处理。如果您的代码是Java,在API中是NIO。唯一的阻止调用将是当您调用selector.select()时,只有在成千上万个套接字上没有要处理的内容时才会被阻止。类似netty.io这样的事件驱动框架使用此模型,已经被证明具有很高的可扩展性,并且最好利用系统的硬件资源。


-2

我建议使用像Akka这样的框架来管理线程。使用Jersey http客户端库,它支持非阻塞IO,并且可以通过回调函数进行操作。这可能是处理此类任务的理想设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接