FIFO queue to guarantee ordered "processing" of messages (multiple consumers)?

706 views
Skip to first unread message

Dasith Wijesiriwardena

unread,
Dec 8, 2016, 2:59:47 AM12/8/16
to rabbitmq-users
I just came home after an interesting interview. They asked me some fairly common questions around RabbitMQ. One answer we agreed to disagree on. :D

Scenario.
You have multiple publishers sending events (messages) to RabbitMQ (via EasyNetQ) about certain topics. They said they guarantee FIFO. They want to architect a system that guarantees "processing" of messages for a "topic" in order.

My solution:
 
Have a cache that holds a "version number" per topic and hold processing of the message if the sequence didn't match. You can retry processing of the message (time delayed retry) after the first event processing completes and updates the cache to the new target version. This means that the consumer is basically waiting on another consumer to complete processing. This works for things that take magnitudes of milliseconds not seconds as it's kind of a lock.

Alternatively I said we could implement a holding table for events out of order like this http://blog.jonathanoliver.com/cqrs-out-of-sequence-messages-and-read-models/

They said both those answers were incorrect.

The solution they said was to use a routing key and a direct exchange and have topics always go the same consumer. Kind of a sticky load balancing system.
I pointed out that this limits the on demand scalability of the system as exchanges/bindings would need to be updated depending on the number of consumers up at any point in time.

I would really like to get the opinion of someone who's implemented this pattern before. Is there a right and wrong solution here or is it a case of choosing the right strategy based on processing delays, scalability, etc?

Michael Klishin

unread,
Dec 8, 2016, 4:25:14 AM12/8/16
to rabbitm...@googlegroups.com
There are many approaches to ordering in a concurrent system. I would seriously question
anyone who claims there is a single preferred solution. This will vary between workloads,
domains, programming languages, libraries used, and so on.

That said, some solutions are easier to reason about than others. "Consumer stickiness", if you can
achieve it in your case, is perhaps one of the more straightforward ones. Keep in mind that
consumers can fail and therefore you'd need to have redundant consumers at some point.
Which is the same problem with different options available. Concurrency challenges are fractal.

One thing worth mentioning is that sometimes you want consumer coordination. RabbitMQ is NOT
a great tool for coordination. See ZooKeeper, etcd, and similar.

HTH.


--
You received this message because you are subscribed to the Google Groups "rabbitmq-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rabbitmq-users+unsubscribe@googlegroups.com.
To post to this group, send email to rabbitmq-users@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
MK

Staff Software Engineer, Pivotal/RabbitMQ
Reply all
Reply to author
Forward
0 new messages