ZeroMQ/ZMQ 推/拉模式的用处 [英] ZeroMQ/ZMQ Push/Pull pattern usefulness

查看:31
本文介绍了ZeroMQ/ZMQ 推/拉模式的用处的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在试验 ZeroMQ Push/Pull(他们称之为 Pipeline)套接字类型时,我很难理解这种模式.它被称为负载平衡器".

In experimenting with the ZeroMQ Push/Pull (what they call Pipeline) socket type, I'm having difficulty understanding the utility of this pattern. It's billed as a "load-balancer".

给定一个服务器向多个工作线程发送任务,推/拉将在所有客户端之间平均分配任务.3个客户端和30个任务,每个客户端得到10个任务:client1得到任务1、4、7、... client2、2、5、...等等.很公平.字面上地.

Given a single server sending tasks to a number of workers, Push/Pull will evenly hand out the tasks between all the clients. 3 clients and 30 tasks, each client gets 10 tasks: client1 gets tasks 1, 4, 7,... client2, 2, 5,... and so on. Fair enough. Literally.

然而,在实践中,通常存在任务复杂性或客户端计算资源(或可用性)的非同质混合,然后这种模式会被严重破坏.所有的任务似乎都是提前安排好的,服务器不知道客户端的进度,甚至不知道它们是否可用.如果 client1 出现故障,它的剩余任务不会发送到其他客户端,而是继续排队等待 client1.如果 client1 保持关闭,则永远不会处理这些任务.相反,如果客户端处理其任务的速度更快,则它不会获得更多任务并保持空闲状态,因为它们仍为其他客户端安排.

However, in practice there is often a non-homogeneous mix of task complexity or client compute resources (or availability), then this pattern breaks badly. All the tasks seem to be scheduled in advance, and the server has no knowledge of the progress of the clients or if they are even available. If client1 goes down, its remaining tasks are not sent to the other clients, but remain queued for client1. If client1 remains down, then those tasks are never handled. Conversely, if a client is faster at processing its tasks, it doesn't get further tasks and remains idle, as they remain scheduled for the other clients.

使用REQ/REP 是一种可能的解决方案;然后只将任务分配给可用资源.

Using REQ/REP is one possible solution; tasks are then only given to an available resource .

所以我错过了什么吗?Push/Pull 如何有效使用?有没有办法用这种套接字类型处理客户端、任务等的不对称性?

So am I missing something? How is Push/Pull to be used effectively? Is there a way to handle the asymmetry of clients, tasks, etc, with this socket type?

谢谢!

这是一个简单的 Python 示例:

Here's a simple Python example:

# server

import zmq
import time

context = zmq.Context()
socket = context.socket(zmq.PUSH)
#socket = context.socket(zmq.REP)   # uncomment for Req/Rep

socket.bind("tcp://127.0.0.1:5555")

i = 0
time.sleep(1)   # naive wait for clients to arrive

while True:
  #msg = socket.recv()    # uncomment for Req/Rep
  socket.send(chr(i))
  i += 1 
  if i == 100:
    break

time.sleep(10)   # naive wait for tasks to drain

.

# client

import zmq
import time
import sys

context = zmq.Context()

socket = context.socket(zmq.PULL)
#socket = context.socket(zmq.REQ)    # uncomment for Req/Rep

socket.connect("tcp://127.0.0.1:5555")

delay = float(sys.argv[1])

while True:
  #socket.send('')     # uncomment for Req/Rep
  message = socket.recv()
  print "recv:", ord(message)
  time.sleep(delay)

在命令行上使用延迟参数(即 1、1 和 0.1)启动 3 个客户端,然后启动服务器,看看所有任务是如何均匀分布的.然后杀死其中一个客户端以查看其剩余任务未处理.

Fire up 3 clients with a delay parameter on the command line (ie, 1, 1, and 0.1) and then the server, and see how all the tasks are evenly distributed. Then kill one of the clients to see that its remaining tasks aren't handled.

取消注释指示将其切换到 Req/Rep 类型套接字并观察更有效的负载平衡器的行.

Uncomment the lines indicated to switch it to a Req/Rep type socket and watch a more effective load-balancer.

推荐答案

这不是负载均衡器,这是一个错误的解释,在 0MQ 文档中停留了一段时间.要进行负载平衡,您必须从工作人员那里获取一些有关其可用性的信息.PUSH 和 DEALER 一样,是一个循环分配器.它的原始速度和简单性很有用.您不需要任何喋喋不休,只需将任务推向管道,然后在网络可以处理它们的情况下尽快将它们发送给所有可用的工作人员.

It's not a load balancer, this was a faulty explanation that stayed in the 0MQ docs for a while. To do load-balancing, you have to get some information back from the workers about their availability. PUSH, like DEALER, is a round-robin distributor. It's useful for its raw speed, and simplicity. You don't need any kind of chatter, just pump tasks down the pipeline and they're sprayed out to all available workers as rapidly as the network can handle them.

当您执行大量小任务并且工人很少来往时,该模式很有用.该模式不适用于需要时间才能完成的大型任务,因为这样您就需要一个队列,只将新任务发送给可用的工作人员.它还受到反模式的影响,如果客户端发送许多任务然后工作人员连接,第一个工作人员将获取 1,000 条左右的消息,而其他工作人员仍在忙于连接.

The pattern is useful when you are doing really high numbers of small tasks, and where workers come and go infrequently. The pattern is not good for larger tasks that take time to complete because then you want a single queue that sends new tasks only to available workers. It also suffers from an anti-pattern where if a client sends many tasks and then workers connect, the first worker will grab 1,000 or so messages while the others are still busy connecting.

您可以通过多种方式创建自己的更高级别的路由.查看指南中的 LRU 模式:在此工作人员明确告诉代理准备好".您还可以进行基于信用的流量控制,这就是我在任何实际负载平衡情况下都会做的.它是 LRU 模式的概括.请参阅 http://hintjens.com/blog:15

You can make your own higher-level routing in several ways. Look at the LRU patterns in the Guide: in this the workers explicitly tell the broker 'ready'. You can also do credit-based flow control, and this is what I'd do in any real load-balancing situation. It's a generalization of the LRU pattern. See http://hintjens.com/blog:15

这篇关于ZeroMQ/ZMQ 推/拉模式的用处的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆