[zeromq-dev] Java/Windows issues

Martin Sustrik sustrik at fastmq.com
Thu Aug 20 10:16:04 CEST 2009


Robin,

>     It's doable and the use case is a valid one so only question is
>     whether to implement it in 0MQ/1.0 or rather postpone it for 0MQ/2.0.
> 
> 
> Sounds like you need to replace PGM (e.g. w/ UDP), right? Thats a pretty 
> big job, I'd just implement in 0MQ2.

Actually, no. Both can be implemented on top of PGM. However, user has 
to choose which mechanism to use (1-to-many or many-to-many) as the 
semantics are slightly different.

As for UDP I would avoid our own implementation of reliable multicast. 
Doing it from scratch would mean simply throwing away hundreds of 
manyears and experience invested into PGM.

The background is that 0MQ is trying to leverage existing technology 
rather than reinvent the wheel. That's the way to keep it thin and 
ultra-efficient.

The examples are:

1. Use processor's synchronisation mechanism (locking the memory bus) 
rather than software-based locking (mutexes) for inter-thread 
synchronisation.

2. Use IP multicast instead of middleware-level TCP-based message 
distribution. The work is done by he hardware of the IP switch rather 
than by software-based message broker. In other words custom pub-sub 
mechanism is (at least partially) replaced by standard IGMP-based 
subscriptions.

3. Use IP multiplexing implemented in HW rather than middleware-level 
SW-based one (see AMQP channel concept for instance).

4. Use DNS name resolving mechanism rather than custom name resolving 
(applies only to 0MQ/2.0).

etc.

> Not a bad thing really as it allows you to eventually implement a lot of 
> fancy stuff: your own session ids/seq numbers for recovery which can 
> then be used further up the stack e.g. for persistent solutions, checks 
> for duplicate publishers of the same session, awareness of other 
> publishers/listeners and knowing when they arrive/disappear and what seq 
> numbers they are up to, throttling listeners who request recovery too 
> much, etc.

I would rather try to think about how to build these features on the top 
of the existing stack.

>     That's the way the multicast group works. Consumers are going to get
>     everything. Filtering on the topic is done on the consuming side.
> 
> 
> Understood, but some middleware implementations have the concept of 
> topics built in and filter before queueing the message to the app. Also 
> they may have out of process software message switches which receive 
> multicast and filter by topic before delivering to your process over 
> TCP. Sometimes useful if you have UI's that you don't want directly 
> connected to a high volume multicast group. I think this can just be 
> implemented as a wrapper around a lower level layer like below. This way 
> the overhead isn't there when you don't need it.

There are two distinct ideas here AFAIU:

1. Consumers would publish special subscribe/unsubscribe messages on the 
bus which would allow producers not to physically send any messages that 
have no consumers. The obvious problem are late-joining producers - they 
would have to get a snapshot of current subscriptions either from a 
centralised repository or from each consumer. Also, consumers would have 
to be monitored and subscriptions should be deleted when a consumer dies 
unexpectedly. The whole thing is more or less doable, but pretty complex.

2. Intermediate message switch. Yes, that's something that can be done 
in the future.

>         ZSock sock = new ZSock("pgm://eth0;239.151.1.1:100
>         <http://239.151.1.1:100> <http://239.151.1.1:100>");
> 
>         sock.addZSockListener( new ZSockListener() {
>          void disconnected() {}
>          void connected() {}
>         });
> 
>         ZRecoverableSock recovSock = new ZRecoverableSock ("Instance1",
>         sock);//first param is the persistent name which remains the
>         same across restarts so listeners can identify the sender even
>         it is moved to a different host
> 
> 
>     Yes. But would work only for unicast based transports as discussed
>     above.
> 
> 
> Why? The ZRecoverableSock will write every message from a file and can 
> replay the messages when any listener requests them. Any listener can 
> request a resend. You may want to add features so listeners request 
> replays over TCP or at least receive the replays over unicast UDP, so 
> you don't bog down other listeners. You could also add options to make 
> it aware if subscribers and tracks which messages have been received by 
> which subscriber and then removes the messages that no longer need to be 
> stored.

The slow consumer problem. With TCP you can simply block the producer 
when consumer is not consuming fast enough and there's no more 
memory/disk space to store the messages to send. With multicast the same 
strategy would result in whole system blocking because of a single 
misbahaved/slow consumer.


>         You could also have a ZReqReplySock that wraps any of the above
>         sockets.
> 
> 
>     Will be done in 0MQ/2.0
> 
> OK, I'm curious to see how thats implemented in multicast. Does everyone 
> see the responses and have to filter them?

No point in implementing req/rep on top of multicast. It's always 1-to-1 
dialogue.

>     Additional sequence numbers on top of TCP/PGM are unaviodable for
>     guaranteed delivery (the one that survives component restart). As
>     you say, UDP is an option, however, it would mean reimplementing all
>     the nice TCP functionality (thing of congestion control mechanisms)
>     so I believe few additional bytes per message are worth of it.
> 
> 
> Congestion control is nice for point to point. Doesn't really apply much 
> in multicast of course, just because one guy goes down doesn't mean 
> anybody else is throttled.

There've been some research done on the topic. I've personally liked the 
PGMCC by Luigi Rizzo. The paper should be available on the web in case 
you are interested.

Martin



More information about the zeromq-dev mailing list