[zeromq-dev] Load balancing REQ/REP sockets
Jon Dyte
jon at totient.co.uk
Wed Mar 17 08:50:58 CET 2010
Brian Granger wrote:
> Hi,
>
> REQ/REP sockets have a load balancing feature. If you have 1 master
> with a REQ socket that binds:
>
> ctx = zmq.Context()
> s = ctx.socket(zmq.REQ)
> s.bind('tcp://127.0.0.1:5555')
>
> And multiple workers that connect REP sockets to the REQ:
>
> # Each worker does this.
> ctx = zmq.Context()
> s = ctx.socket(zmq.REP)
> s.connect('tcp://127.0.0.1:5555')
>
> When the master does a send, the requests will be load balanced to all
> connected workers. That works fine.
>
> But, a REQ socket cannot do another send until it gets back a reply
> (by doing a recv). So here is my question:
>
> How can you actually get load balancing in practice if the REQ socket
> in the master cannot issue another send
> (to a different worker) until first worker has replied. Another way
> of putting this is I don't see how to get the multiple
> workers handling requests *simultaneously*. Am I missing something or
> is this by design.
>
> I can see how to accomplish this pattern with P2P sockets, but it
> would require a much more complicated application logic to implement.
>
> thoughts?
>
> Cheers,
>
> Brian
>
>
you can get load balancing from multiple REQ sockets, but each
individual REQ socket
effectively serialises each req and reply as far as I understand.
to do this intra-process you do something like see attached zmqserver.cpp
which uses Xrep/xreq with a client like
// zmq
#include <zmq.hpp>
#include <unistd.h>
#include <iostream>
#include <stdio.h>
int main(int argc , char*argv[])
{
zmq::context_t ctx (1, 1);
zmq::socket_t s (ctx, ZMQ_REQ);
s.connect ("tcp://127.0.0.1:43210");
for (unsigned char i = 'A' ; i < 'Z' ; ++i)
{
zmq::message_t request(1);
*((char*)request.data()) = i;
printf("send %x\n", (int) *((char*)request.data()));
s.send(request);
zmq::message_t response;
s.recv(&response);
printf("recv %x\n", (int) *((char*)response.data()));
sleep(::getpid()%3);
}
return 0;
}
you can also use the zmq_queue device which does the same thing but
doesnt use the inprocess endpoints.
thus you can have
REQ*<->SHARED_QUEUE(XREP,XREQ) <->REP*
* multiple of these, 1 shared queue.
caveat at the moment you have to do some special processing in the REP
socket.
Normally i have the shared queue do the binds for the xrep,xreq sockets
and then
the workers(REP) and clients(REQ) connect to that.
There is a working zmq_queue device in the latest release.
does this make sense?
Jon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: zmqserver.cpp
Type: text/x-c++src
Size: 3498 bytes
Desc: not available
URL: <https://lists.zeromq.org/pipermail/zeromq-dev/attachments/20100317/c1123dfc/attachment.cpp>
More information about the zeromq-dev
mailing list