使用zeromq实现任务农场消息传递模式
我正在使用zeromq来解决一个问题,这个问题涉及到几百个(可能是几千个)客户端请求执行任务。每个客户端都会请求执行一个特定的任务,完成后结果会返回给发出请求的客户端。
到目前为止,我已经识别出了以下几个角色,构成了我设计的模式:
- 客户端:这个角色是请求执行一项工作的(或称为“任务”)
- 控制器:这个角色负责将“任务”在可用的引擎之间进行负载均衡
- 引擎:这个角色接收来自控制器的任务请求,并将结果发布回客户端。
我还没有想出引擎是如何将消息发送回客户端的。我猜测,使用zeromq实现这一点的一种方式可能是:
客户端:
在一个套接字上向控制器发送任务消息,同时在另一个套接字上订阅引擎发布的完成结果控制器:
从客户端的一个套接字上接收任务消息,同时在另一个套接字上向引擎发布任务消息(显然,这将是一个转发设备)引擎:
在一个套接字上订阅任务消息,同时在另一个套接字上发布结果
如果有人能提供一个框架或代码片段,展示如何使用zeromq实现这个模式,那将非常有帮助。
代码片段可以用C、C++、PHP、Python或C#编写
[[编辑]]
在阅读了关于任务农场的内容后(正如akappa所建议的)。我认为这个问题确实可以通过任务农场来建模。我已经相应地修改了我最初的角色(并且也更改了标题)。
如果有人熟悉zeromq,能勾勒出一个框架,展示我如何使用核心组件来构建这样的框架,那将非常有用。
2 个回答
这是一种经典的主从并行模式(也叫“农场”或“任务农场”)。
实现这种模式的方法有很多种。这里提供了一种使用MPI实现的方法,也许能给你在zeromq中实现这个模式带来一些灵感。
有很多方法可以实现这个功能,IPython.parallel 提供了两种使用 ZeroMQ 的实现方式:一种是简单的纯 ZeroMQ,另一种则更复杂,控制器是用 Python 实现的。
我们把控制器分成了两个部分:
- 中心(Hub) - 这是一个独立的进程,它能看到所有的通信,负责跟踪集群的状态,把结果推送到数据库等,并通知客户端引擎的连接和断开。
- 调度器(Scheduler) - 本质上是一个简单的 ROUTER-DEALER 设备,负责把客户端的请求转发给引擎,并把回复再送回去。
看看我们架构中任务分配的部分:
- 调度器是一个 0MQ 队列设备,包含一个 ROUTER 和一个 DEALER 插口,两个都在运行。
- 客户端有 DEALER 插口,连接到调度器的 ROUTER。
- 引擎有 ROUTER 插口,连接到调度器的 DEALER。
这利用了以下两个特点:
- DEALER 可以在多个同伴之间均衡负载请求。
- ROUTER 使用身份前缀将回复发送回发起特定请求的同伴。
这是一个使用 pyzmq 的简单负载均衡任务农场,它能把回复路由回请求的客户端:https://gist.github.com/1358832
还有一种替代方案,结果会发送到其他地方,而不是返回给请求的客户端,这就是 0MQ 指南中的 通风口-水槽模式。