1. 程式人生 > >基於Redis的三種分散式爬蟲策略

基於Redis的三種分散式爬蟲策略

前言:

爬蟲是偏IO型的任務,分散式爬蟲的實現難度比分散式計算和分散式儲存簡單得多。
個人以為分散式爬蟲需要考慮的點主要有以下幾個:

  • 爬蟲任務的統一排程
  • 爬蟲任務的統一去重
  • 儲存問題
  • 速度問題
  • 足夠“健壯”的情況下實現起來越簡單/方便越好
  • 最好支援“斷點續爬”功能

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框架的爬蟲也適用。Master端壓力比較小,Master與Slaver的資料交流也不大。
缺點: “健壯性”不夠,需要另外定時儲存待爬佇列以實現“斷點續爬”功能。各Slaver的待爬任務不通用。

結語:

如果把Slaver比作工人,把Master比作工頭。策略一就是工人遇到新任務都上報給工頭,需要幹活的時候就去工頭那裡領任務;策略二就是工頭去找新任務,工人只管從工頭那裡領任務幹活;策略三就是工人遇到新任務時詢問工頭此任務是否有人做了,沒有的話工人就將此任務加到自己的“行程表”。