Scrapy分布式原理

蓝咒 提交于 2020-03-04 05:14:58

scrapy架构

首先我们先看一下Scrapy的单机架构
在这里插入图片描述
也就是说scrapy的单机架构实际上实在本机维护一个爬取队列,用Scheduler进行调度,如果我们要实现scarpy的分布式,就需要多台主机协同操作,那么问题来了

多台主机协作的关键是什么?

实际上就是共享爬取队列:核心就是将这个队列进行共享,让多台主机都能访问,然后让各个主机的Scheduler进行调度,这样就可以共享requests,进行统一的抓取。

  • 单主机爬虫架构: 主机从Queue中抓取队列,然后由Scheduler调度
    在这里插入图片描述
  • 分布式爬虫架构: 由多个Scheduler从同一个Queue中调度,这样就可以完成协同的抓取
    在这里插入图片描述
    前面写到的这些,都离不开队列,那么怎么维护队列呢

队列用什么维护?

可能大家会想到使用数据库,使用文件或者一些特定的数据结构来进行维护,这里推荐redis队列,那么redis有什么好处呢?

  • Redis是非关系型数据库,以Key-Value形式进行存储,相对于其他数据库来说,结构跟灵活
  • 是内存中的数据结构存储系统,处理速度快,性能好。
  • 提供队列,集合等多种存储结构,分辨队列维护。

怎么去重?

在进行抓取中,因为有多台主机访问一个队列,所以他们请求到的url可能会相同,那么抓取到的数据可能会一样,那么我们要怎么保证各个主机拿到的requests队列是不重复的呢?
这里我们可以使用Redis集合。存储每个reuqest指纹

  • Redis提供集合数据结构,在Redis集合中存储每个request的指纹。
  • 在向request队列中加入Request前首先验证这个request的指纹是否已经加入集合中。
  • 如果以存在,则不添加request到队列,如果不存在,则将request添加入队列并将指纹加入集合中

怎样防止中断

因为有多台机器在运行,可能会出现一些意外状况导致程序突然中断,比如:家里电脑被女朋友砸了,或者断电停网什么的🤔,那么我们应该怎么来防止程序中断呢?
这里scrapy有一个启动判断

  • 在每台从机Scrapy启动时都会首先判断当前Redis Request队列是否为空
  • 如果为空,则重新开始爬取,第一台从机执行爬取向队列中添加request。
  • 如果不为空,则从队列中取得下一个Request执行爬取
    所以在程序中断时,它会判断里面的Request队列是否为空,然后做出相应的操作,所以影响并不是很大。

怎样实现该架构?

说了这么多,我们需要维护request队列,需要多台从机执行程序,还需要一个redis去重的机制,那么我们应该怎么实现这个架构呢?
那么这里就可以使用一个功能强(xiu)大(de)无(fei)比(qi)的库,scrapy-redis,关于前面我们所提到的问题,它都已经解决了。我们只需要使用这个库,它就可以很完美的配合scrapy来完成分布式架构的爬取了。

Scrapy-Redis

pip install scrapy-redis  # 安装命令
Scrapy-Redis
Scrapy-Redis实现了如上架构,改写了Scrapy的调度器,
队列等组件。 利用他可以方便的实现Scrapy分布式架构。

链接地址:Scrapy-Redis的github地址, 在这地址中有一些关于Scrapy-Redis的基本用法

scrapy-redis源码链接:Scrapy-Redis源码
在这里插入图片描述
关于这里面的各个文件,我就不一一介绍了,大家感兴趣可以去看看。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!