ZeroMQ通知客户彼此

时间:2014-05-14 16:06:44

标签: zeromq

我希望将重型计算任务并行化到多个工作计算机上,这些计算机必须在彼此之间共享数据。我有一台服务器,所有工作人员都可以连接并了解他们的“邻居”,以便他们可以连接到他们并交换数据。这是我想到的结构图: system structure

正如你所看到的,每个节点都有4个邻居(我不想在图片中画更多)。我根本没有固定套接字类型,我只是认为它们是最好的选择。

但似乎ZeroMQ无法将有关一个连接的连接信息传达给另一个连接。因为我认为这实际上是一项非常常见的任务,所以必须有一个解决方案。 网络的类型可以变化,它可以是标准的tcp / ip网络,只有一堆通过路由器链接的计算机,或通过infiniband连接的集群。基本上我想要的是一个字符串,我可以简单地在一个客户端插入connect()或bind(),而不必担心协议和网络类型以及所有这些 - 这正是我理解zeromq试图完成的内容

提前感谢您的回答! :)

编辑:这是我想到的一个示例性沟通:

WorkerMiddle.sendToServer("Hey server, please tell me my neighbours")
Server.sendToWorkerMiddle(Worker.top.connectionInfo())
WorkerMiddle.connectTo(WorkerTop)
Server.sendToWorkerMiddle(Worker.bottom.connectionInfo())
WorkerMiddle.connectTo(WorkerBottom)
Server.sendToWorkerMiddle(Worker.left.connectionInfo())
WorkerMiddle.connectTo(WorkerLeft)
Server.sendToWorkerMiddle(Worker.right.connectionInfo())
WorkerMiddle.connectTo(WorkerRight)

1 个答案:

答案 0 :(得分:2)

您对ZMQ套接字类型,协议和寻址有些误解。我会先尝试解决这个问题,以便你能够继续前进。

ZMQ绝对抽象出使用像TCP这样的网络协议的细节,但是当你通过网络进行通信时,你仍然必须告诉它使用TCP,而你仍然会使用良好的'IP地址或DNS名称,可以将您的同行彼此联系起来。

因此,对于您的情况,每个工作节点将具有IP地址和/或DNS名称。如果你提前知道这些,你甚至不需要向服务器/主机询问它们,你可以立即连接到一个工人到另一个工人的IP地址。相反,如果服务器/主服务器有此信息而工作人员没有在启动时,那么工作人员可以请求IP地址列表,主服务器可以发送它...然后它连接到IP地址对象就像它一样,例如,当它连接到主服务器时。

服务器

// obviously this code will change depending on the language/binding that you use
// this is psuedo-code
server = new zmq.socket('ROUTER');
server.bind('tcp://10.20.30.40:55555');

worker1

worker1 = new zmq.socket('REQ');
worker1.connect('tcp://10.20.30.40:55555');

worker2

worker2 = new zmq.socket('REQ');
worker2.connect('tcp://10.20.30.40:55555');

...您指出PAIR套接字似乎最适合您连接工作者,但它们仅适用于从一个线程到另一个线程的单个多线程应用程序之间的通信,因此这不是你在这里寻找的东西。相反,您可能希望每个工作者都有自己的路由器套接字,并且您可以根据需要创建新的req套接字以连接到每个对等端:

worker1

worker1 = new zmq.socket('REQ');
peer1 = new zmq.socket('ROUTER');
peer1.bind('tcp://10.20.30.41:44444');
worker1.connect('tcp://10.20.30.40:55555');

peers = worker1.send('tell me my peers');
for (i=0; i<peers.length; i++) {
    peer_array[i] = new zmq.socket('REQ');
    peer_array[i].connect('tcp://' . peers[i]);
}

worker2

worker2 = new zmq.socket('REQ');
peer2 = new zmq.socket('ROUTER');
peer2.bind('tcp://10.20.30.42:33333');
worker2.connect('tcp://10.20.30.40:55555');

peers = worker2.send('tell me my peers');
for (i=0; i<peers.length; i++) {
    peer_array[i] = new zmq.socket('REQ');
    peer_array[i].connect('tcp://' . peers[i]);
}

......这里发生的是每个工作者都在设置一个请求套接字来连接到其他工作者的路由器。服务器将发回ipaddress:port。

形式的字符串列表

在不知道从服务器到工作人员或从工作人员到工作人员传递什么类型的信息的情况下,提供比您可能选择的套接字更好的建议是不可能的,但至少这假定客户端/服务器请求/回复系统类型。

如果您感兴趣,我们可以更深入地了解您为什么要做出这些特别的选择,或者如果您仍然卡住了,请在评论中告诉我。