首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试用ZeroMQ构建分布式爬虫

尝试用ZeroMQ构建分布式爬虫
EN

Stack Overflow用户
提问于 2013-10-16 13:38:04
回答 1查看 1.2K关注 0票数 3

我刚开始学习ZeroMQ,想要在学习的同时构建一个分布式的网络爬虫作为一个例子。

我的想法是使用PHP编写一个"server",它接受爬行应该从哪里开始的url。

工作人员(C# cli)将不得不爬行该url,提取链接,并将它们推回服务器上的堆栈中。服务器一直将堆栈中的urls发送给工作人员。也许redis会跟踪所有爬行的urls,所以我们不会多次抓取站点,并且能够提取当前进程的统计信息。

我希望服务器能够均匀地分配任务,注意新的/丢失的工作人员,并在员工没有响应时重新分发urls。

为什么PHP用于服务器:我只是对PHP非常满意,仅此而已。我不想让这个例子/测试项目变得更复杂。

为什么C#为仆从:因为它运行在大多数windows机器上。我可以把可执行文件交给不同的朋友,他们可以执行它,并帮助我测试我的项目。

爬行过程和redis功能不是我问题的一部分。

我的第一种方法是推拉模式,它通常适用于我的场景,但不知道它是仆从。我想我需要一个中间商/路由器经纪人,我必须自己处理工人的意识。

我找到了this question,但我不确定我是否理解答案.

我要求提供一些如何影响zmq的提示。经销商的做法正确吗?有什么办法能让员工自动意识到吗?我认为我需要一些资源/示例,还是您认为我只需要深入了解zmq指南?

然而,一些指向正确方向的暗示将是很棒的:)

干杯

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-17 02:09:06

我正在构建一个作业/任务分发程序,它的工作原理至少与您的爬虫相同。以下是我学到的一些东西:

定义所有事件

服务器和爬虫之间的通信将基于系统中发生的不同事情,例如将工作从服务器发送到爬虫,或者爬虫向服务器发送心跳消息。定义系统的事件类型;它们是用例:

代码语言:javascript
复制
DISPATCH_WORK_TO_CRAWLER_EVENT
CRAWLER_NODE_STATUS_EVENT
...

定义消息标准

服务器和爬虫之间的所有通信都应该使用ZMsg进行,因此定义一个组织框架的标准,如下所示:

代码语言:javascript
复制
Frame1: "Crawler v1.0"             //this is a static header
Frame2: <event type>               //ex: "CRAWLER_NODE_STATUS_EVENT"
Frame3: <content xml/json/binary>  //content that applies to this event (if any)

现在,您可以创建消息验证器来验证在对等点之间接收到的ZMsgs,因为您有一个所有消息都必须遵循的标准约定。

服务器

使用服务器上的单个ROUTER与爬虫进行异步和双向通信。此外,使用PUB套接字广播心跳消息。

不要阻塞路由器套接字,使用POLLER每5s或任何东西循环一次,这允许服务器定期执行其他事情,比如向爬行器广播心跳事件;如下所示:

代码语言:javascript
复制
Socket rtr = .. //ZMQ.ROUTER
Socket pub = .. //ZMQ.PUB  
ZMQ.Poller poller = new ZMQ.Poller(2)
poller.register( rtr, ZMQ.Poller.POLLIN)                               
poller.register( pub, ZMQ.Poller.POLLIN)

  while (true) {
     ZMsg msg = null            
     poller.poll(5000)

     if( poller.pollin(0)){
        //messages from crawlers                         
        msg = ZMsg.recvMsg(rtr)
     }

     //send heartbeat messages
     ZMsg hearbeatMsg = ...
     //create message content here,
     //publish to all crawlers
     heartbeatMsg.send(pub)
  }

为了解决有关员工意识的问题,一种简单有效的方法使用FIFO堆栈和心跳消息,如下所示:

  • 服务器在内存中维护一个简单的FIFO堆栈。
  • 服务器发出心跳;爬行器使用其节点名称进行响应;路由器也会自动将节点的地址放在消息中(在message enveloping上读取)
  • 将1对象推到包含节点名称和节点地址的堆栈上。
  • 当服务器想要将工作分派给爬虫时,只需从堆栈中弹出下一个对象,就可以正确地创建消息和地址(使用节点地址),然后将其交给该工作人员。
  • 以同样的方式向其他爬虫分派更多的工作;当爬虫返回服务器时,只需将另一个具有节点名称/地址的对象推回堆栈;其他工作人员在响应之前是不可用的,因此我们不会打扰他们。

这是一种简单而有效的基于工人可用性的分配工作的方法,而不是盲目地分发工作。查看lbbroker.php示例,概念是相同的。

爬虫(工人)

工作人员应该使用一个DEALER套接字和一个SUBDEALER是异步通信的主套接字,子订阅来自服务器的心跳消息。当工作人员接收到心跳消息时,它将响应到经销商套接字上的服务器。

代码语言:javascript
复制
Socket dlr = .. //ZMQ.DEALER
Socket sub = .. //ZMQ.SUB
ZMQ.Poller poller = new ZMQ.Poller(2)
poller.register( dlr, ZMQ.Poller.POLLIN)                               
poller.register( sub, ZMQ.Poller.POLLIN)

  while (true) {
     ZMsg msg = null            
     poller.poll(5000)

     if( poller.pollin(0)){
        //message from server                         
        msg = ZMsg.recvMsg(dlr)
     }

     if( poller.pollin(1)){
      //heartbeat message from server
       msg = ZMsg.recvMsg(sub)
       //reply back with status
       ZMsg statusMsg = ...
       statusMsg.send(dlr)
  }

剩下的你自己算出来。通过PHP的例子,构建东西,打破它,构建更多,这是你学习的唯一途径!

玩得开心,希望它能帮上忙!

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19405005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档