[rabbitmq-discuss] [Q] best way to add a sequencer to the broker

Ben Hood 0x6e6562 at gmail.com
Mon Dec 29 18:29:51 GMT 2008


Chuck,

On Mon, Dec 29, 2008 at 5:43 PM, Chuck Remes <cremes.devlist at mac.com> wrote:
> Your last sentence quoted above gets it exactly. Each publisher will
> set the sequence number to 0 so that the republisher/sequencer service
> can add the global number stamp to it. I guess the publishers could
> also set it to nil; the initial value is irrelevant since the
> Sequencer will overwrite it.

Fair point. It need not be set until it passes through the broker.
FWIW there are some standard header properties that could be misused
for this purpose, e.g. the message_id field.

> The use case is to stamp a global order on all messages through the
> broker for the purposes of replay, debugging and async logging. I
> realize that during normal operation the services will be publishing
> messages in an arbitrary order; it doesn't matter to me. I need to
> recreate that arbitrary order *exactly* for a replay.

What is the scope of the stamp? Is it globally monotonic

a) accross the entire Rabbit cluster
b) within a single Rabbit node
c) within a single AMQP channel
d) just through a particular queue

?

Obviously, as the scope widens the throughput will become more serial.

And the last option is a giveaway - at the queue level you get the
ordering *for free*.

> Think of the sequencer as the software equivalent of a hardware bus
> clock. Alternately, think of the sequencer as the equivalent of adding
> an identity column to a database table (this column contains a
> monotonically increasing integer assigned by the server).

Strict ingress ordering is going to cost more than global identity,
which could be achieved by a guid, for example.

A timestamp would be cheaper, but than would not be strictly ordered,
just asymptotically.

> I think this does solve the issue. I don't know Erlang yet so I'll
> probably keep the Sequencer as an external Java client for the short-
> term, but it's nice to know I can get a performance win with a rewrite
> in Erlang. Avoiding the TCP overhead, even if it is short circuited on
> a localhost, is a good thing.

What would be more efficient would be a custom exchange implementation
that stamps each message as it passes through, because you would avoid
the delivery-redelivery overhead. This would also mean less moving
parts.

In contrast to the Erlang AMQP client, this would involve some coding
in the server.


> As other services declare exchanges and publish to them, I would like
> my Sequencer to dynamically detect the existence of a new Exchange so
> it can create a queue, bind the new queue to the Exchange and receive
> messages from it for processing and republishing.

ATM there is no notification facility present in Rabbit to tell
somebody that an exchange has been created. One could extend Rabbit to
do this (which wouldn't be rocket science) or you could also do this
on the application level, i.e. maintain a notification queue that the
sequencer listens on, and have whoever creates a new exchange also
post to this queue.

HTH,

Ben




More information about the rabbitmq-discuss mailing list