Skip to content

Optimise fanout exchange #14531

@ansd

Description

@ansd

Is your feature request related to a problem? Please describe.

The fanout exchange can be optimised. A lot of CPU time is wasted due to ets:select/2 compiling the same match spec for every message.

For example, if a single classic queue is bound to a fanout exchange and a client publishes to that fanout exchange as fast as possible rabbit_exchange:route() wastes about 12% of CPU time.

Describe the solution you'd like

Do not use ets:select/2.

Possible solutions (just brainstorming, haven't tried them out):

  • Use another routing projection where the ETS table key is only the SourceExchange rather than {SourceExchange, BindingKey}. Downside: more memory usage for that additional ETS table
  • Ignore the binding key for fanout exchanges and store the binding key as the empty string, a bit similarly as being forced in the local random exchange in
    validate_binding(_X, #binding{key = BKey}) ->
    {error, {binding_invalid,
    "Non empty binding '~s' key not permitted",
    [BKey]}}.
    Downside: backward compat issues?

Additional context

Similar enhancement was done in #4606

Some other exchange types (in addition to the fanout exchange) suffer exactly the same performance issue:

  • rabbit_exchange_type_recent_history
  • rabbit_exchange_type_random
  • rabbit_sharding_exchange_type_modulus_hash

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions