Avoid ETS lookup if no extra_bcc queue set #4787
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
A queue (Q1) can have an extra_bcc queue (Q2).
Whenever a message is routed to Q1, it must also be routed to Q2.
Commit fc2d37e (in 3.10.x, but not in 3.9.x) puts the logic to determine extra_bcc queues into
rabbit_exchange:route/2
.That is functionally correct because it ensures that messages being dead lettered to target queues will also route to the target queues' extra_bcc queues. For every message being routed, that commit uses
ets:lookup/2
just to check for an extra_bcc queue (blue rectangle D below).Technically, that commit is not a regression because it does not slow down the common case where a message is routed to a single target queue because before that commit
rabbit_channel:deliver_to_queues/3
used twoets:lookup/2
calls (blue rectangles A and B below).However we can do better by avoiding the
ets:lookup/2
for the common case where there is no extra_bcc queue set.One option is to use
ets:lookup_element/3
to only fetch the queueoptions
field as demonstrated here.A better option (implemented in this PR) is determining whether to send to an extra_bcc queue in the rabbit_channel and in the at-most and at-least once dead lettering modules where the queue records have already been looked up.
Performance
Single node RabbitMQ cluster and latest Java perf-test client running both on the same Intel NUC11 with 8 CPUs, 32GB RAM, Ubuntu 22.04, Erlang OTP 25.0-rc3.
RabbitMQ server started via
advanced.config
2 publishers sending to a stream:
Sending rate avg (msgs/s):
3.9.17: 252k - 260k
3.10.1: 250k - 262k
PR: 259k - 273k
CPU Flame Graphs
3.9.17
A is this line
B is this line
3.10.1
C is this line
D is this line
This PR
No additional ETS lookup and therefore faster routing.