使用zeromq实现任务农场消息传递模式

4 投票
2 回答
1714 浏览
提问于 2025-04-17 04:33

我正在使用zeromq来解决一个问题,这个问题涉及到几百个(可能是几千个)客户端请求执行任务。每个客户端都会请求执行一个特定的任务,完成后结果会返回给发出请求的客户端。

到目前为止,我已经识别出了以下几个角色,构成了我设计的模式:

  • 客户端:这个角色是请求执行一项工作的(或称为“任务”)
  • 控制器:这个角色负责将“任务”在可用的引擎之间进行负载均衡
  • 引擎:这个角色接收来自控制器的任务请求,并将结果发布回客户端。

我还没有想出引擎是如何将消息发送回客户端的。我猜测,使用zeromq实现这一点的一种方式可能是:

客户端:
在一个套接字上向控制器发送任务消息,同时在另一个套接字上订阅引擎发布的完成结果

控制器:
从客户端的一个套接字上接收任务消息,同时在另一个套接字上向引擎发布任务消息(显然,这将是一个转发设备)

引擎:
在一个套接字上订阅任务消息,同时在另一个套接字上发布结果

如果有人能提供一个框架或代码片段,展示如何使用zeromq实现这个模式,那将非常有帮助。

代码片段可以用C、C++、PHP、Python或C#编写

[[编辑]]

在阅读了关于任务农场的内容后(正如akappa所建议的)。我认为这个问题确实可以通过任务农场来建模。我已经相应地修改了我最初的角色(并且也更改了标题)。

如果有人熟悉zeromq,能勾勒出一个框架,展示我如何使用核心组件来构建这样的框架,那将非常有用。

2 个回答

3

这是一种经典的主从并行模式(也叫“农场”或“任务农场”)。

实现这种模式的方法有很多种。这里提供了一种使用MPI实现的方法,也许能给你在zeromq中实现这个模式带来一些灵感。

5

有很多方法可以实现这个功能,IPython.parallel 提供了两种使用 ZeroMQ 的实现方式:一种是简单的纯 ZeroMQ,另一种则更复杂,控制器是用 Python 实现的。

我们把控制器分成了两个部分:

  1. 中心(Hub) - 这是一个独立的进程,它能看到所有的通信,负责跟踪集群的状态,把结果推送到数据库等,并通知客户端引擎的连接和断开。
  2. 调度器(Scheduler) - 本质上是一个简单的 ROUTER-DEALER 设备,负责把客户端的请求转发给引擎,并把回复再送回去。

看看我们架构中任务分配的部分:

  • 调度器是一个 0MQ 队列设备,包含一个 ROUTER 和一个 DEALER 插口,两个都在运行。
  • 客户端有 DEALER 插口,连接到调度器的 ROUTER。
  • 引擎有 ROUTER 插口,连接到调度器的 DEALER。

这利用了以下两个特点:

  • DEALER 可以在多个同伴之间均衡负载请求。
  • ROUTER 使用身份前缀将回复发送回发起特定请求的同伴。

这是一个使用 pyzmq 的简单负载均衡任务农场,它能把回复路由回请求的客户端:https://gist.github.com/1358832

还有一种替代方案,结果会发送到其他地方,而不是返回给请求的客户端,这就是 0MQ 指南中的 通风口-水槽模式

撰写回答