[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