对于商业数据,目前常用的是采用分布式架构实现在短时间内完成一轮的数据爬取。一般分布式爬虫由若干个分布式层级组成。下图所示的一个例子,该分布式爬虫由分布式数据中心、分布式抓取服务器和分布式爬虫程序组成;而整个爬虫系统再有多个分布式数据中心组成。每个数据中心负责抓取其周边的网页。每个数据中心由高速网络连接的多台抓取服务器组成。而每个抓取服务器下面又可以部署多个爬虫程序。通过上述多层级的分布式爬虫体系,才能够保证抓取数据的及时性和全面性。
一般来说,抓取服务器之间不同的分工协作方式对应不同的分布式架构:主从式分布爬虫和对等分布爬虫。
1)主从分布式爬虫
该类分布式爬虫系统中将抓取服务器分为两类:URL服务器和抓取服务器。URL服务器主要维护待抓取的URL队列,并将其按照各个抓取服务器的空闲状态分配抓取任务。此外,URL服务器还可以对各个抓取服务器之间的负载进行均衡,使得各个抓取服务器的资源得到合理利用,而不至于某些抓取服务器过闲,而某些过忙。不同的抓取服务器之间是无需通讯的,仅仅需要与URL服务器进行通讯。
由于URL服务器承担很多的管理任务,且待抓取的URL数量巨大,URL服务器容易成为整个分布式系统的瓶颈。
2)对等分布式爬虫
该分布式系统中每台服务器的角色相同,各自承认一部分的URL抓取。由于没有URL服务器,所以,需要面临每个抓取服务器的任务分工问题。下图的对等分布式系统:
每个服务器自己判断是否对该URL进行抓取,还是将该URL转发给其他的抓取服务器呢?其判断的依据是对网址的主域名进行hash,之后再根据抓取服务器的数量进行取模。有点儿像是通过hash计算出一个编号,再根据服务器的数量对该编号取模,使得该编号能够落在对应的服务器编号上。如是不匹配,则将其转发到所计算出的服务器编号上。
上面的例子可以看出有3台服务器,所以取模的时候,是对3进行取的。1号服务器负责抓取hash取模为1的URL。当其接收到网址为www.google.com时,先计算其主域名hash,之后再对其取3的模,发现为1,则属于自己的职责,对该URL进行下载。这样每台服务器平均负担1/3的抓取工作量。
由于其哈希函数不是针对整个URL,而是仅仅针对主域名,这样能够保证同一网站的内容由同一抓取服务器进行负责抓取。这样一方面可以提供DNS域名解析的缓存,提高下载效率,另一方面也可以主动控制该网站的访问,避免对网站的访问量多大,减轻网站的访问压力。
但是当某台抓取服务器出现宕机之后,m值便发生变化,这直接导致大部分URL哈希之后取模的值将发生变化,使得几乎所有的任务需要重新计算和再分配,直接导致资源的巨大浪费。为此,提出的UbiCrawler爬虫,该爬虫系统放弃哈希取模的方法,而是采用一致性哈希方法来进行任务的分工。该方法也是对主域名进行哈希,哈希范围在0~2^32之间的数值,同时将最小值0和最大值重合,这样形成一个环形序列。将抓取服务器也按照环形进行排列,各个抓取服务负责抓取这个环形序列的一个片段,即落在某个哈希取值范围内的URL都由该服务器进行抓取。由于是环形的,所以当其中某台抓取服务器宕机之后,按照环形顺时针顺序查找,将URL转发给第一个碰到的服务器。直到该宕机的服务器恢复之后。如此某个服务器宕机之后并不会其他服务器的任务产生影响,便解决了哈希取模方式的弊端。将影响范围从全局限制到了局部,如是新加入一台服务器也是如此。