Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unexpected: synchronous publishing without pub confirms is slower than with confirms #60

Open
vitaly-krugl opened this issue May 14, 2015 · 4 comments

Comments

@vitaly-krugl
Copy link

Running both RabbitMQ 3.5.1 and test app on my recent model development MacBookPro (OS X Yosemite), I encountered unexpected, reproducible performance conundrum: with pubacks=False, synchronous publishing is consistently slower than with pubacks=True. This is counterintuitive and differs from all other AMQP clients that I profiled.

I used the apps from https://github.com/vitaly-krugl/amqp-perf to profile basic_publish performance. Below are a few examples of what I am talking about.

puka with pubacks=False

I verified that the channel IS NOT in confirm mode

time python puka_perf.py publish --impl=Client --exg="" --size 1024 --msgs=100000

real    0m22.728s
user    0m12.593s
sys 0m2.129s

puka with pubacks=True

I verified that the channel IS in confirm mode

time python puka_perf.py publish --impl=Client --exg="" --size 1024 --msgs=100000 --delivery-confirmation

real    0m17.368s
user    0m9.054s
sys 0m2.112s

Here, you can see that both real and user execution times are smaller for pubacks=True. This is unexpected, because with pubacks=True the broker needs to check whether the exchange exists before it can Ack, whereas with pubacks=False, the broker can Ack right away.

Below are a couple of comparable tests and corresponding execution times for haigha:

haigha with pubacks=False

time python haigha_perf.py publish --impl=SocketTransport --exg="" --size 1024 --msgs=100000

real    0m10.010s
user    0m7.772s
sys 0m2.231s

haigha with pubacks=True

time python haigha_perf.py publish --impl=SocketTransport --exg="" --size 1024 --msgs=100000 --delivery-confirmation

real    0m21.344s
user    0m13.371s
sys 0m3.531s
@majek
Copy link
Owner

majek commented May 14, 2015

Puka treats your message delivery serious.

When you publish with pubacks=False, what do you actually mean by saying "synchronous"? Usually people mean: being sent off the networks. For puka this is not enough and it actually tries to synchronize with the server to make sure it was indeed delivered. That means that publishing in pubacks=False mode is two operations: async publish followed by sync something to synchronize.

If you wish higher speed with pubacks=False, please send many messages, gather a number of promises and wait for them all at once.

@vitaly-krugl
Copy link
Author

Sorry @majek, let me rephrase: I meant "blocking" via client.wait(client.basic_publish(...). My understanding is that to "synchronize", the client library waits for Basic.Ack in the case of pubacks=False. In the case of of pubacks=True, the client library also waits for Basic.Ack (or the very rare Basic.Nack) and an optional Basic.Return may occur prior to Basic.Ack if the the message was undeliverable.

So, in both scenarios pubacks=False/True, the client library needs to wait for Basic.Ack in order to synchronize with the server. What else does the client library need to do to synchronize with the broker? Thus, it's intuitive to expect that the no-confirms case would be faster than the confirms case, even if sending messages one-at-a-time.

@majek
Copy link
Owner

majek commented May 15, 2015

hmm

If pubacks=True puka uses publisher acks to synchronize. If pubacks=False puka uses some other obscure mechanism to synchronize, since publishes are asycn.

@vitaly-krugl
Copy link
Author

I see, in the pubacks=False case, it "guards" the original message with another message that's guaranteed to be returned:

        eheaders = {'x-puka-delivery-tag': delivery_tag, 'x-puka-footer': True}
        frames = frames + \
                 spec.encode_basic_publish('', '', True, False, eheaders,
                                                '', conn.frame_max)

@majek, My app uses two types of AMQP messaging with respect to delivery guarantees:

  1. Guaranteed delivery of ordered data; relies on publisher acknowledgments with mandatory=True and basic.return support for at-least-once delivery guarantee;
  2. Notifications; prefers speed and no need for guaranteed delivery

For the second scenario, is there a way to configure a puka Client that would disable the extra overhead of the x-puka-delivery-tag business? There are usage scenarios where these "guard" messages are a detractor.

@majek, I am looking for alternatives to my current AMQP client due to licensing incompatibilities, and would like to make an informed decision. In the README, it states

Puka is experimental ... Puka is a side project, written mostly to prove if it is possible to create a reasonable API on top of the AMQP protocol.

Does the above quote mean that there is no motivation to maintain it and that it would be a non-starter for use in production? What is your recommendation? Are a lot of people using it? If I switch to puka, I will be motivated to contribute, but I want to make sure that it's already stable before making the move.

Many thanks,
Vitaly

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants