我的目标是构建一个分布式爬虫,它一次处理超过一个网站,同时也处理多个查询。为此,我使用“请求”和“BeautifulSoup”等标准包在Python中构建了一个web爬虫。效果很好。为了使其分发,我使用了rabbitMQ。它使我能够使系统更快,有超过一个进程,帮助爬行。
我的系统工作在一个工作池模型中:
然而,我在这个体系结构中有一个巨大的瓶颈,它不是主要的服务器.rabbitMQ不允许我一次使用超过一个消息(channel.basic_qos()函数不能工作!)我想要的是为每个查询设置一个私有队列(就像我现在所做的那样),并且能够同时处理这两个查询,并且尽可能快。这意味着,并行化工作人员代码,以便它可以处理最大数量的url,而不是一次一个url。
在这里我应该用什么来代替rabbitMQ呢?我特别接触了rabbitMQ的开发人员,而我想要的东西不能用它来完成,所以我正在尝试找到一个不同的“分发包”。也许是卡夫卡?
发布于 2017-12-30 13:59:22
首先,您必须确定程序的限制是什么。是I/O绑定还是CPU绑定?
例如,如果一个简单的非并行版本的程序可以饱和您的网络连接,那么做一个并行版本是没有用的。
对于网络爬虫来说,网络往往是最终的瓶颈。
但让我们假设您有足够的网络容量。在这种情况下,我建议使用multiprocessing.Pool。充当辅助进程的函数接受URL作为输入,并从URL返回处理过的数据。创建一个池,并使用imap_unordered方法将worker函数应用到URL列表中;
def worker(url):
rv = requests.get(url)
# Do whatever processing is needed.
result = ...
return (url, result)
urls = ['www.foo.com', ...]
p = multiprocessing.Pool()
for url, result in p.imap_unordered(worker, urls):
print('The URL ', url, 'returned ', result)默认情况下,Pool将使用与CPU内核相同的工作人员。使用更多的工人通常是没有用的。
请注意,必须将工作者的返回值从辅助进程返回到父进程。所以它必须是可腌制的。如果您必须返回大量数据,这可能会成为IPC瓶颈。在这种情况下,最好将其写入例如基于RAM的文件系统,然后只返回数据文件的文件名。
https://stackoverflow.com/questions/45400863
复制相似问题