Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RabbitMQ - Message order of delivery

I need to choose a new Queue broker for my new project.

This time I need a scalable queue that supports pub/sub, and keeping message ordering is a must.

I read Alexis comment: He writes:

"Indeed, we think RabbitMQ provides stronger ordering than Kafka"

I read the message ordering section in rabbitmq docs:

"Messages can be returned to the queue using AMQP methods that feature a requeue parameter (basic.recover, basic.reject and basic.nack), or due to a channel closing while holding unacknowledged messages...With release 2.7.0 and later it is still possible for individual consumers to observe messages out of order if the queue has multiple subscribers. This is due to the actions of other subscribers who may requeue messages. From the perspective of the queue the messages are always held in the publication order."

If I need to handle messages by their order, I can only use rabbitMQ with an exclusive queue to each consumer?

Is RabbitMQ still considered a good solution for ordered message queuing?

like image 983
Bick Avatar asked Jan 26 '14 12:01

Bick


People also ask

Are RabbitMQ messages ordered?

From RabbitMQ release 2.7. 0, messages are always held in the queue in publication order, even in the presence of requeueing or channel closure. With release 2.7. 0 and later it is still possible for individual consumers to observe messages out of order if the queue has multiple subscribers.

Does RabbitMQ maintain order?

The RabbitMQ documentation states the following regarding its ordering guarantees: Messages published in one channel, passing through one exchange and one queue and one outgoing channel will be received in the same order that they were sent.

Is RabbitMQ FIFO or LIFO?

Queues in RabbitMQ are FIFO ("first in, first out"). Some queue features, namely priorities and requeueing by consumers, can affect the ordering as observed by consumers.

How does RabbitMQ deliver messages?

Applications can subscribe to have RabbitMQ push enqueued messages (deliveries) to them. This is done by registering a consumer (subscription) on a queue. After a subscription is in place, RabbitMQ will begin delivering messages. For each delivery a user-provided handler will be invoked.


1 Answers

Well, let's take a closer look at the scenario you are describing above. I think it's important to paste the documentation immediately prior to the snippet in your question to provide context:

Section 4.7 of the AMQP 0-9-1 core specification explains the conditions under which ordering is guaranteed: messages published in one channel, passing through one exchange and one queue and one outgoing channel will be received in the same order that they were sent. RabbitMQ offers stronger guarantees since release 2.7.0.

Messages can be returned to the queue using AMQP methods that feature a requeue parameter (basic.recover, basic.reject and basic.nack), or due to a channel closing while holding unacknowledged messages. Any of these scenarios caused messages to be requeued at the back of the queue for RabbitMQ releases earlier than 2.7.0. From RabbitMQ release 2.7.0, messages are always held in the queue in publication order, even in the presence of requeueing or channel closure. (emphasis added)

So, it is clear that RabbitMQ, from 2.7.0 onward, is making a rather drastic improvement over the original AMQP specification with regard to message ordering.

With multiple (parallel) consumers, order of processing cannot be guaranteed.
The third paragraph (pasted in the question) goes on to give a disclaimer, which I will paraphrase: "if you have multiple processors in the queue, there is no longer a guarantee that messages will be processed in order." All they are saying here is that RabbitMQ cannot defy the laws of mathematics.

Consider a line of customers at a bank. This particular bank prides itself on helping customers in the order they came into the bank. Customers line up in a queue, and are served by the next of 3 available tellers.

This morning, it so happened that all three tellers became available at the same time, and the next 3 customers approached. Suddenly, the first of the three tellers became violently ill, and could not finish serving the first customer in the line. By the time this happened, teller 2 had finished with customer 2 and teller 3 had already begun to serve customer 3.

Now, one of two things can happen. (1) The first customer in line can go back to the head of the line or (2) the first customer can pre-empt the third customer, causing that teller to stop working on the third customer and start working on the first. This type of pre-emption logic is not supported by RabbitMQ, nor any other message broker that I'm aware of. In either case, the first customer actually does not end up getting helped first - the second customer does, being lucky enough to get a good, fast teller off the bat. The only way to guarantee customers are helped in order is to have one teller helping customers one at a time, which will cause major customer service issues for the bank.

I hope this helps to illustrate the problem you are asking about. It is not possible to ensure that messages get handled in order in every possible case, given that you have multiple consumers. It doesn't matter if you have multiple queues, multiple exclusive consumers, different brokers, etc. - there is no way to guarantee a priori that messages are answered in order with multiple consumers. But RabbitMQ will make a best-effort.

like image 187
theMayer Avatar answered Sep 22 '22 23:09

theMayer