我正在进行网络爬虫,并使用线程下载页面。
我的程序性能的第一个限制因素是带宽,我无法下载更多的页面。
第二个问题是我所关心的。我正在使用线程同时下载多个页面,但是随着我创建的线程越来越多,处理器共享的负担也越来越大。是否有某些指标/方法/测试类可以确定理想的线程数量或者在达到一定数量后,性能不会再改变或者下降?
我正在进行网络爬虫,并使用线程下载页面。
我的程序性能的第一个限制因素是带宽,我无法下载更多的页面。
第二个问题是我所关心的。我正在使用线程同时下载多个页面,但是随着我创建的线程越来越多,处理器共享的负担也越来越大。是否有某些指标/方法/测试类可以确定理想的线程数量或者在达到一定数量后,性能不会再改变或者下降?
请看看我在这个帖子中的回答
您的示例可能会受到 CPU 绑定的影响,因此您需要一种方法来解决争用问题,以便能够找出在您的机器上使用的正确线程数并使它们保持繁忙。分析将有所帮助,但请记住,它将取决于核心数(以及已经提到的网络延迟等),因此在连接您的线程池大小时,请使用运行时获取核心数。
很抱歉没有快速的答案,恐怕需要进行测试、测量、调整和重复的过程!
理想的线程数应该接近于硬件提供的核心数(虚拟核心)。这是为了避免线程上下文切换和线程调度。如果您正在进行大量的IO操作并且有许多阻塞读取(您的线程在套接字读取上被阻塞),建议您重新设计代码以使用非阻塞IO API。通常,这将涉及一个“选择器”线程,它将监视成千上万个套接字的活动和少量的工作线程来处理。如果您的代码是Java,在API中是NIO。唯一的阻止调用将是当您调用selector.select()
时,只有在成千上万个套接字上没有要处理的内容时才会被阻止。类似netty.io这样的事件驱动框架使用此模型,已经被证明具有很高的可扩展性,并且最好利用系统的硬件资源。
我建议使用像Akka这样的框架来管理线程。使用Jersey http客户端库,它支持非阻塞IO,并且可以通过回调函数进行操作。这可能是处理此类任务的理想设置。