1

我的目標是建立一個分佈式爬行程序,它一次處理多個網站,同時處理多個查詢。 爲此,我使用標準包(如'requests'和'BeautifulSoup')在Python中構建了一個網絡爬蟲。它工作正常。 爲了使它分佈,我使用rabbitMQ。它使我能夠通過一個以上的進程幫助爬網來加快系統的速度。Python中的分佈式計算 - 網絡爬蟲

我的系統工作在一個workpool模型:

  • 我有一個主服務器接收查詢,並開始爲他們每個人一個新的爬行。
  • 開始抓取時,通過將查詢輸入到搜索引擎中來收集一些URL。
  • 從現在開始,主服務器通過rabbitMQ向可用的工作者/進程發送URL,並等待從它們接收更多的URL。

但是,我在這個架構中有一個巨大的瓶頸,它不是主要的服務器... rabbitMQ不允許我一次消耗超過1條消息(channel.basic_qos()函數不會工作!)。 我想要的是爲每個查詢設置一個專用隊列(就像我現在所做的那樣),並且能夠儘可能快地同時處理這兩個查詢。通過這種方式,並行化工人代碼,以便它可以處理最大量的url,而不是一次處理1個url。

我應該用什麼來取代rabbitMQ?我特意到達rabbitMQ的開發人員,而我想要的卻無法完成,所以我試圖找到一個不同的「分發包」。也許卡夫卡?

回答

0

首先,你必須確定你的程序的限制是什麼。它是I/O綁定還是CPU綁定?

E.g.如果一個簡單的非並行版本的程序可以使您的網絡連接飽和,那麼製作並行版本就沒有用處。

對於網絡爬蟲,網絡往往是最終的瓶頸。

但是讓我們假設你有足夠的網絡容量。 在這種情況下,我會建議使用multiprocessing.Pool。 充當工作進程的函數將URL作爲輸入,並從URL中返回已處理的數據。 您可以創建一個池,並使用imap_unordered方法將工作函數應用於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的文件系統,只是返回數據文件的文件名。

+0

感謝您的回答。多處理無疑是並行化的想法。 但是,正如我所說的,我正在使用rabbitmq使分佈式爬蟲(許多計算機/進程可以加入),這就是我造成的瓶頸。 – Skinishh