今天面试, 说到了分布式爬虫, 其实每个框架已经实现了高并发的性能, 通过异步等等方式, 把性能发挥到了极致. 但在做高铁的时候无聊, 便设计了一个非常有意思的架构.

 

这个架构, 是一个思维比较开放形式.主要的思想就是把所有的主要构件拆成单独的worker类型, 然后通过一个总的引擎来控制不同的worker与task, 所有的worker进程为单位, worker内是否需要多线程或异步就看大家自己的需要了, 对于多cpu的服务器可以非常迅速的挖掘潜力,发挥极致的爬取性能.当然我还不知道目前有没有这类架构形式的框架.

如果觉得有问题或需要改进, 欢迎大家发邮件yanwei.li.24#at#gmail.com

以下是随手画的草图.

IMG_20140822_224530

 

详细描述

  • Engine 层的主要作用:
  1. 按需求与比例增加或停止每台机器的worker数量以及worker 比例, 包括 Downloader worker, Parser worker, Pipeline Worker.
  2. 对池子里的任务进行控制, 分发任务到各worker.
  • Downloader Worker:

Downloader可以自由定制, 你可以用nodejs做异步高并发的下载, 也可以用c写出个高效率的Downloader

  • Parser Worker

可以毫无疑问的选用脚本, javascript或者python都可以, 重要的是可以针对不同的parser快速编写, 快速修改.

  • Pipeline

由于可能是远程存储, 也有可能有延迟, 也有可能会断线, 还有可能会分到不同的块区等等, 这些逻辑都在这里写就可以了, 这个有时候你会觉得更像个Uploader.

 

Pools:

  1. 每个worker完成一个小任务单元都需要把结果存储到下一个pool里, 所有的worker等待Engine分发task.
  2. 如果有pool产生堵塞, 减少上层worker的数量, 增加下层worker数量.
  3. 如果pool内的task消耗很快, 甚至总是让池子空了, 增加上层worker数量, 减少下层worker数量.
  4. Engine发放task要以组发放, 一组task=1 batch, 这样发放任务会减少分发运算与上下文数量.

 

该架构的优点

  1. 天然的分布式, 线性增加机器即可.所有任务共享, 共同消化, 宕机机器后任务仍然精准完成.
  2. 天然多进程, 程序调度与性能发挥不需要额外处理, 完全依靠系统足够.
  3. worker独立, 可以自由定制, 针对不同的worker类型进行优化.
  4. worker分离, 通过引擎的控制可以让不同类型的Worker工作协调, 资源分配均匀, 无浪费.
  5. 轻量与定制方便, 队友合作可以不关心谁用什么语言, 抓取用c, 解析用javascript, 上传再来一个pythoner做, 只要pool格式做好, 其他都ok.

架构很粗糙, 但我还需要给这个架构添加点血肉.

要有血有肉

Master-Engine

Local-Engine

–Downloader
—-some-downloader1
—-some-downloader1_lib
—-some-downloader2
–Paser
—-some-parser1
—-some-parser2
—-some-parser2_lib
–Pipeline
—-some-pipeline1
—-some-pipeline1_lib
—-some-pipeline2

我们大体约定 Request的格式,  id,url,some-downloader,retry_time,status,created_time,meta_data

我们大体约定 Response的格式,  id,url,some-parser,response-context,status,meta_data

我们对item的约定是 item_name,some-pipeline,value(dict)

 

这样整个任务流就完成了.

为了能够反反爬虫, 比如某个downloader,  如果一旦某网站被进止抓取,比如跳转到输入验证码页, 可以写不同的downloader的wrapper来引用不同的middleware.

该middleware的作用就是向engine做出反馈, 然后engine会通知所有的downloader, downloader把任务放回池子里, 如果验证码不通过, engine不会分发该网站的task.

 

计算机软件应该包括程序与数据, 也可以完全叫做数据的集合, 因为cpu处理的一切都是在靠一些逻辑数据处理一些人需要的数据. Lisp中有说: “代码即数据”, 就是这个意思.

对于爬虫, 最重要的不是架构, 不是效率, 而是数据的完整.

而不管是什么架构的设计, 先忘掉设计模式, 忘掉异常处理, 忘掉所有的乱起八糟, 然后回头围绕数据来做, 事情就会得到极大的简化, 也就是经典.

本文说的架构就是围绕数据而发散来的.