Topic Exchange vs Direct Exchange in RabbitMQ
Asked Answered
G

5

62

We've got an application which will be using RabbitMQ and have several different queues for passing messages between tiers.

Initially, I was planning to use multiple direct exchanges, with one for each message type, but it looks like having a single topic exchange with queues using different routing key bindings will achieve the same thing.

Having a single exchange also seems like it would be a bit easier to maintain, but I was wondering if there is any benefit (if any) of doing it one way over the other?

Option 1, using multiple direct exchanges:

ExchangeA (type: direct)
-QueueA

ExchangeB (type: direct)
-QueueB

ExchangeC (type: direct)
-QueueC

Option 2, using single topic exchange:

Exchange (type: topic)
-QueueA  (receives messages from exchange with routing key of "TypeA")
-QueueB  (receives messages from exchange with routing key of "TypeB")
-QueueC  (receives messages from exchange with routing key of "TypeC")
Grotesque answered 14/3, 2012 at 15:7 Comment(1)
You can possibly learn the differences here #9705090 jstobigdata.com/rabbitmq/topic-exchange-in-amqp-rabbitmqChristychristye
D
42

Assuming both models are being considered to be implemented using one broker running, there's little difference that I can see.

Option 2 seems more common in the real world for solving this kind of routing problem (at least in my anecdotal experience) and it's exactly the challenge that Topic Exchanges exist to solve.

The only difference that you might encounter would relate to routing speed. I don't know for sure if Exchange routing (based always on an exact string match) is faster in RabbitMQ when compared to the routing key technique used in Topic Exchanges (which can include wildcards like # and *). My hunch would be that Exchange discrimination would be faster, but you could experiment for yourself to find out, or try contacting the RabbitMQ team to ask them.

Finally, if you go with option 1 end up with lots of queues then you'll have a proportional proliferation of Exchanges. That sounds like a maintenance headache. If you'll only have a handful of queues then it won't be too much of an issue.

Diastrophism answered 14/3, 2012 at 20:20 Comment(3)
I concur. Multiple queues with appropriate routing keys is far easier to manage. The only advantage of option 1 that springs to mind is that multiple exchanges could be hosted on separate hardware thereby achieving vertical scaling. However, if your hardware rocks then you may never need to take this route.Westminster
I think the advantage of using Topic is if it happens in the future that you need to send the same message to multiple queues in your exchange, your option 2 would be more desirable.Kalagher
Note that using Direct Exchange when having multiple consumers it will work as a fanout and send the message to all connected users.Meanwhile, the topic Exchange queues will handle consumers in a round robin basedSpherule
S
27

Indeed approach 2 is better as it gives you flexibility to use a single queue for multiple routing keys.

Exchange Topic

QueueA-- binding key = India.Karnataka.*

You can route a message to topic exchange with routing key as India.Karnataka.bangalore,India.Karnataka.Mysore.

All the above messages goes to QueueA.

Direct Exchange

But I did not understand on why are you creating multiple direct exchanges in approach 1. You can have single direct exchange and have multiple queues with each queue binding with a unique key.

QueueA-- binding key = Key1
QueueB-- binding Key = Key2
QueueC-- binding Key = Key3

All key1 messages goes to QueueA.Key2 goes to QueueB ... You can still maintain single direct exchange.

Syriac answered 25/4, 2017 at 15:44 Comment(3)
Will keeping a single direct exchange affect the performance?Latrice
Why cant we use fanout instead of topic?Cooperate
@ujwaldhakal because it is not so versatile, the topic can act like direct and fanout. BTW fanout will just blindly distribute messages to queues.Jeth
H
7

For a single small node with little load there is little difference. Most people go with option two for said reasons above.

When designing the system you should ask your self how might this expand in the future.

How is it going to scale ?
Do I need it to scale ? Do I want to add a high a availability cluster in the future ? Is my routing going to change...

Option 2 provides a lot more flexibility in most cases.

It allows you to do things like attach a new consumer to the Exchange with its own queue and capture any subset or all of your message flow easily. ( these queues could be on other nodes in a cluster or mirrored to n nodes providing failover) A typical use case would be logging all messages using a 4th queue.

If your bottleneck is on the processing side, You can also further subdivide your message topics and perform some amount of prioritization with out having to change your publishers. Example: ToppicA.urgent, processed by dedicated consumer, TopicA.log eventually processed.

The short answer is go with option 2 unless you have very specific performance requirements, If for example you need to process say a sustained rate of more than 50k msg/s you might want to think about option 1 on dedicated nodes, but for normal flows option 2 will be easier to scale and maintain.

Henn answered 15/4, 2015 at 5:19 Comment(0)
L
1

Direct exchange also supports multiple routes (https://www.rabbitmq.com/tutorials/amqp-concepts.html#exchange-direct) , so why don't you use something like this:

ExchangeA (type: direct)
-QueueA
-RoutingA

ExchangeB (type: direct)
-QueueB
-RoutingB

ExchangeC (type: direct)
-QueueC
-RoutingC
Leede answered 21/8, 2019 at 20:50 Comment(0)
F
0

One thing that should also be considered is, that your code for publishing the messages will look slightly different when you publish to different exchanges vs. when you publish to a single exchange but only with different routing keys.

Keep in mind that your code needs to know the names of the different exchanges from somewhere (probably from configuration) and you have to maintain kind of a mapping between exchanges and routing keys. Also with direct exchanges in RabbitMQ, the routing key needs to exactly match the queue names. So your code then needs to know the queue names too to be able to set the correct routing keys.

When using a single exchange (no matter if direct or topic) your code only needs to deal with one exchange and the routing keys.

Fallonfallout answered 11/2, 2020 at 15:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.