
對(duì)于商業(yè)搜索引擎來說,分布式爬蟲架構(gòu)是必須采用的技術(shù)。面對(duì)海量待抓取網(wǎng)頁,只有采用分布式架構(gòu),才有可能在較短時(shí)間內(nèi)完成一輪抓取工作。
分布式爬蟲可以分為若干個(gè)分布式層級(jí),不同的應(yīng)用可能由其中部分層級(jí)構(gòu)成。大型分布式爬蟲主要分為以下3個(gè)層級(jí):分布式數(shù)據(jù)中心、分布式抓取服務(wù)器及分布式爬蟲程序。整個(gè)爬蟲系統(tǒng)由全球多個(gè)分布式數(shù)據(jù)中心共同組成,每個(gè)數(shù)據(jù)中心負(fù)責(zé)抓取本地區(qū)周邊的互聯(lián)網(wǎng)網(wǎng)頁,比如歐洲的數(shù)據(jù)中心抓取英國、法國、德國等歐洲國家的網(wǎng)頁,由于爬蟲與要抓取的網(wǎng)頁地緣較近,在抓取速度上會(huì)較遠(yuǎn)程抓取快很多。
每個(gè)數(shù)據(jù)中心又由多臺(tái)高速網(wǎng)絡(luò)連接的抓取服務(wù)器構(gòu)成,而每臺(tái)服務(wù)器又可以部署多個(gè)爬蟲程序。通過多層級(jí)的分布式爬蟲體系,才可能保證抓取數(shù)據(jù)的及時(shí)性和全面性。
對(duì)于同一中心的多臺(tái)抓取服務(wù)器,不同機(jī)器之間的分工協(xié)同方式會(huì)有差異,常見的分布式架構(gòu)有兩種:主從分布爬蟲和對(duì)等分布爬蟲。
主從式分布爬蟲
對(duì)于主從分布式爬蟲,不同的服務(wù)器承擔(dān)不同的角色分工,其中有一臺(tái)專門負(fù)責(zé)對(duì)其他服務(wù)器提供URL分發(fā)服務(wù),其他機(jī)器則進(jìn)行實(shí)際的網(wǎng)頁下載。URL服務(wù)器維護(hù)待抓取URL隊(duì)列,并從中獲得待抓取網(wǎng)頁的URL,分配給不同的抓取服務(wù)器,另外還要對(duì)抓取服務(wù)器之間的工作進(jìn)行負(fù)載均衡,使得各服務(wù)器承擔(dān)的工作量大致相等,不至于出現(xiàn)忙閑不均的情況。抓取服務(wù)器之間沒有通信聯(lián)系,每個(gè)待抓取服務(wù)器只和URL服務(wù)器進(jìn)行消息傳遞。

Google在早期即采用此種主從分布式爬蟲,在這種架構(gòu)中,因?yàn)閁RL服務(wù)器承擔(dān)很多管理任務(wù),同時(shí)待抓取URL隊(duì)列數(shù)量巨大,所以URL服務(wù)器容易成為整個(gè)系統(tǒng)的瓶頸。
對(duì)等式分布爬蟲
在對(duì)等式分布爬蟲體系中,服務(wù)器之間不存在分工差異,每臺(tái)服務(wù)器承擔(dān)相同的功能,各自負(fù)擔(dān)一部分URL的抓取工作,下圖是其中一種對(duì)等式分布爬蟲,Mercator爬蟲采用此種體系結(jié)構(gòu)。
由于沒有URL服務(wù)器存在,每臺(tái)待抓取服務(wù)器的任務(wù)分工就成為問題。在下圖所示的體系結(jié)構(gòu)下,有服務(wù)器自己來判斷某個(gè)URL是否應(yīng)該由自己來抓取,或者將這個(gè)URL傳遞給相應(yīng)的服務(wù)器。至于采取的判斷方法,則是對(duì)網(wǎng)址的主域名進(jìn)行哈希計(jì)算,之后取模(即hash【域名】%m,這里的m為服務(wù)器個(gè)數(shù)),如果計(jì)算所得的值和服務(wù)器編號(hào)匹配,則自己下載該網(wǎng)頁,否則將網(wǎng)址轉(zhuǎn)發(fā)給對(duì)應(yīng)編號(hào)的抓取服務(wù)器。

以上圖的例子來說,因?yàn)橛?臺(tái)服務(wù)器,所以取模的時(shí)候m設(shè)定為3,圖中的1號(hào)抓取服務(wù)器負(fù)責(zé)抓取哈希取模后值為1的網(wǎng)頁,當(dāng)其接受到網(wǎng)址www.google.com時(shí),首先利用哈希函數(shù)計(jì)算這個(gè)主域名的哈希值,之后對(duì)3取模,發(fā)現(xiàn)取模后值為1,屬于自己的職責(zé)范圍,于是就自己下載網(wǎng)頁;如果接受到網(wǎng)頁www.baidu.com,哈希后對(duì)3取模,發(fā)現(xiàn)值等于2,不屬于自居的職責(zé)范圍,則會(huì)將這個(gè)要下載的URL轉(zhuǎn)發(fā)給2號(hào)服務(wù)器,由2號(hào)抓取服務(wù)器來進(jìn)行下載。通過這種方式,每臺(tái)服務(wù)器平均承擔(dān)大約1/3的抓取工作量。
由于沒有URL分發(fā)服務(wù)器,所以此種方法不存在系統(tǒng)瓶頸問題,另外其哈希數(shù)不是針對(duì)整個(gè)URL,而只針對(duì)主域名,所以可以保證同一網(wǎng)站的網(wǎng)頁都由同一臺(tái)服務(wù)器抓取,這樣一方面可以提高下載效率(DNS域名解析可以緩存),另外一方面也可以主動(dòng)控制對(duì)某個(gè)網(wǎng)站的訪問速度,避免對(duì)某個(gè)網(wǎng)站訪問壓力過大。
上圖這種體系結(jié)構(gòu)也存在一些缺點(diǎn),假設(shè)在抓取過程中某個(gè)服務(wù)器宕機(jī),或者此時(shí)新加入一臺(tái)抓取服務(wù)器 ,因?yàn)槿∧r(shí)m是以服務(wù)器個(gè)數(shù)確定的,所以此時(shí)m值發(fā)生變化,導(dǎo)致發(fā)部分URL哈希取模后的值跟著變化,這意味著幾乎所有任務(wù)都需要重新進(jìn)行分配,無疑會(huì)導(dǎo)致資源的極大浪費(fèi)。
為了解決哈希取模的對(duì)等式分布爬蟲存在的問題,UbiCrawler爬蟲提出了改進(jìn)方案,即放棄哈希取模方式,轉(zhuǎn)而采用一致性哈希方法來確定服務(wù)器的任務(wù)分工。
一致性哈希將網(wǎng)站的主域名進(jìn)行哈希,映射為一個(gè)范圍在0到2的32次方之間的某個(gè)數(shù)值,大量的網(wǎng)站主域名會(huì)被平均的哈希到這個(gè)數(shù)值區(qū)間??梢匀缦聢D所示那樣,將哈希值范圍首尾相接,即認(rèn)為數(shù)值0和最大值重合,這樣可以將其看做有序的環(huán)狀序列,從數(shù)值0開始,沿著環(huán)的順時(shí)針方向,哈希值逐漸增大,直到環(huán)的結(jié)尾。而某個(gè)抓取服務(wù)器則負(fù)責(zé)這個(gè)環(huán)裝序列的一個(gè)片段,即落在某個(gè)哈希取值范圍內(nèi)的URL都由該服務(wù)器負(fù)責(zé)下載。這樣即可確定每臺(tái)服務(wù)器的職責(zé)范圍。
我們以下圖為例說明其優(yōu)勢(shì),假設(shè)2號(hào)抓取服務(wù)器接收到了域名www.baidu.com,經(jīng)過哈希值計(jì)算后,2號(hào)服務(wù)器知道在自己的管轄范圍內(nèi),于是自己下載這個(gè)URL。在此之后,2號(hào)服務(wù)器收到了www.sina.com.cn這個(gè)域名,經(jīng)過哈希計(jì)算,可知是3號(hào)服務(wù)器負(fù)責(zé)的范圍,于是將這個(gè)URL轉(zhuǎn)發(fā)給3號(hào)服務(wù)器。如果3號(hào)服務(wù)器死機(jī),那么2號(hào)服務(wù)器得不到回應(yīng),于是知道3號(hào)服務(wù)器出了狀況,此時(shí)順時(shí)針按照環(huán)的大小順序查找,將URL轉(zhuǎn)發(fā)給第一個(gè)碰到的服務(wù)器,即1號(hào)服務(wù)器,此后3號(hào)服務(wù)器的下載任務(wù)都由1號(hào)服務(wù)器接管,直接到3號(hào)服務(wù)器重新啟動(dòng)為止。

從上面的流程可知,即使某臺(tái)服務(wù)器出了問題,那么本來應(yīng)該由這臺(tái)服務(wù)器負(fù)責(zé)URL則由順時(shí)針的下一個(gè)服務(wù)器接管,并不會(huì)對(duì)其他服務(wù)器的任務(wù)造成影響,這樣就解決了哈希取模方式的弊端,將影響范圍從全局限制到了局部,如果新加入下一臺(tái)服務(wù)器也是如此。
如果您對(duì)爬蟲有興趣,還可以閱讀: