question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`DirectExchange` type always lookup for queue in `delivery` method

See original GitHub issue

I have profiled the apply_async method, and I’ve figured out that a lot of time is being spend on _lookup method in exchange module if redis is the backend for celery(thus calling SMEMBERS function). I didn’t find a clean way to add another exchange type, so in the end I’ve monkey patched the DirectExchange type to only execute _put method. I would appreciate if someone could point out how can I define custom exchange type.

Check out the snakeviz(profile) graph: publish_task You can see^ that 22.7s are being spent on the _lookup method, even more time than for the actual _put method.

So is this _lookup really required, and could it be skipped without monkey patching?

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:12 (12 by maintainers)

github_iconTop GitHub Comments

3reactions
thedrowcommented, Apr 3, 2019

To be honest, I haven’t looked into the implementation of the Redis broker at all.

The only place we call SMEMBERS is in get_table(): https://github.com/celery/kombu/blob/3a0454c21d5eee7b641af31ac6e046296aa38d57/kombu/transport/redis.py#L824-L830

get_table() is called in _lookup() as you said: https://github.com/celery/kombu/blob/3a0454c21d5eee7b641af31ac6e046296aa38d57/kombu/transport/virtual/base.py#L700-L726

Since we’re talking about the direct exchange we can use SISMEMBER instead to check if a queue with the same name exists in the set.

We could introduce a _lookup_direct method to the virtual channel which will do so when needed.

Care to provide the PR?

1reaction
matteiuscommented, Aug 29, 2019

@stevanmilic I think there is a caveat to what you are saying. get_table calls smemebers O(n) which has to retrieve all the memebers for the set from redis which could be many, and then to parse that in Python. Instead Redis sismember just checks if the one member is a member of that set and returns a boolean which is O(1) – my optimization in the other PR calls just sismember by not calling get_table – so technically get_table is the performance because it is O(n) and now the reids _lookup implemetnation calls scard and sismemember which are both O(1).

See: https://redis.io/commands/smembers https://redis.io/commands/scard https://redis.io/commands/sismember

Thats why if you can profile this again, I think it will perform better for even users that don’t check of the exchange still exists.

Read more comments on GitHub >

github_iconTop Results From Across the Web

AMQP 0-9-1 Model Explained - RabbitMQ
A direct exchange delivers messages to queues based on the message routing key. A direct exchange is ideal for the unicast routing of...
Read more >
Queues and messages in queues in Exchange Server
In Exchange 2016 and Exchange 2019, queues hold messages before, during, and after delivery. Queues exist in the Transport service on ...
Read more >
pamqp.commands — pamqp 3.2.1 documentation
This method binds a queue to an exchange. Until a queue is bound it will not receive any messages. In a classic messaging...
Read more >
Working with RabbitMQ exchanges and publishing messages ...
A direct exchange delivers messages to queues based on a message routing key, an attribute that every AMQP v0.9.1 message contains. Here is...
Read more >
Sending the first messages | RabbitMQ Essentials
That being said, always specify the content type so that messages are ... declaring a queue as durable and setting the message delivery...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found