爬蟲是偏IO型的任務,分佈式爬蟲的實現難度比分佈式計算和分佈式存儲簡單得多。
我的覺得分佈式爬蟲須要考慮的點主要有如下幾個:redis
Python分佈式爬蟲比較經常使用的應該是scrapy框架加上Redis內存數據庫,中間的調度任務等用scrapy-redis模塊實現。
此處簡單介紹一下基於Redis的三種分佈式策略,其實它們之間仍是很類似的,只是爲適應不一樣的網絡或爬蟲環境做了一些調整而已(若有錯誤歡迎留言拍磚)。 數據庫
【策略一】
Slaver端從Master端拿任務(Request/url/ID)進行數據抓取,在抓取數據的同時也生成新任務,並將任務拋給Master。Master端只有一個Redis數據庫,負責對Slaver提交的任務進行去重、加入待爬隊列。服務器
優勢: scrapy-redis默認使用的就是這種策略,咱們實現起來很簡單,由於任務調度等工做scrapy-redis都已經幫咱們作好了,咱們只須要繼承RedisSpider、指定redis_key就好了。
缺點: scrapy-redis調度的任務是Request對象,裏面信息量比較大(不只包含url,還有callback函數、headers等信息),致使的結果就是會下降爬蟲速度、並且會佔用Redis大量的存儲空間。固然咱們能夠重寫方法實現調度url或者用戶ID。 網絡
【策略二】
這是對策略的一種優化改進:在Master端跑一個程序去生成任務(Request/url/ID)。Master端負責的是生產任務,並把任務去重、加入到待爬隊列。Slaver只管從Master端拿任務去爬。架構
優勢: 將生成任務和抓取數據分開,分工明確,減小了Master和Slaver之間的數據交流;Master端生成任務還有一個好處就是:能夠很方便地重寫判重策略(當數據量大時優化判重的性能和速度仍是很重要的)。
缺點: 像QQ或者新浪微博這種網站,發送一個請求,返回的內容裏面可能包含幾十個待爬的用戶ID,即幾十個新爬蟲任務。但有些網站一個請求只能獲得一兩個新任務,而且返回的內容裏也包含爬蟲要抓取的目標信息,若是將生成任務和抓取任務分開反而會下降爬蟲抓取效率。畢竟帶寬也是爬蟲的一個瓶頸問題,咱們要秉着發送儘可能少的請求爲原則,同時也是爲了減輕網站服務器的壓力,要作一隻有道德的Crawler。因此,視狀況而定。 框架
【策略三】
Master中只有一個集合,它只有查詢的做用。Slaver在遇到新任務時詢問Master此任務是否已爬,若是未爬則加入Slaver本身的待爬隊列中,Master把此任務記爲已爬。它和策略一比較像,但明顯比策略一簡單。策略一的簡單是由於有scrapy-redis實現了scheduler中間件,它並不適用於非scrapy框架的爬蟲。scrapy
優勢: 實現簡單,非scrapy框架的爬蟲也適用。Master端壓力比較小,Master與Slaver的數據交流也不大。
缺點: 「健壯性」不夠,須要另外定時保存待爬隊列以實現「斷點續爬」功能。各Slaver的待爬任務不通用。 分佈式
結語: 若是把Slaver比做工人,把Master比做工頭。策略一就是工人遇到新任務都上報給工頭,須要幹活的時候就去工頭那裏領任務;策略二就是工頭去找新任務,工人只管從工頭那裏領任務幹活;策略三就是工人遇到新任務時詢問工頭此任務是否有人作了,沒有的話工人就將此任務加到本身的「行程表」。