none
How do I improve performance while doing pull, push and delete from Azure Storage Queue

    Question

  •        

    Hi,

    I am working on a distributed application with Azure Storage Queue for message queuing. queue will be used by multiple clients across the clock and thus it is expected that it would be heavily loaded most on the time in usage. business case is typical as in it pulls message from queue, process the message then deletes the message from queue. this module also sends back a notification to user indicating process is complete. functions/modules work fine as in they meet the logical requirement. pretty typical queue scenario.

    Now, coming to the problem statement. since it is envisaged that the queue would be heavily loaded most of the time, I am pushing towards to speed up processing of the overall message lifetime. the faster I can clear messages, the better overall experience it would be for everyone, system and users.

    To improve on performance I did multiple cycles for performance profiling and then improving on the identified "HOT" path/function.

    It all came down to a point where only the Azure Queue pull and delete are the only two most time consuming calls outside. I can further improve on pull, which i did by batch pulling 32 message at a time (which is the max message count i can pull from Azure queue at once at the time of writing this question.), this returned me a favor as in by reducing processing time to a big margin. all good till this as well.
    i am processing these messages in parallel so as to improve on overall performance.

    pseudo code:

    //AzureQueue Class is encapsulating calls to Azure Storage Queue.
    //assume nothing fancy inside, vanila calls to queue for pull/push/delete
    var batchMessages = AzureQueue.Pull(32);            Parallel.ForEach(batchMessages, bMessage =>
                {
                  //DoSomething does some background processing;
                  try{DoSomething(bMessage);}
                  catch()
                  {
                   //Log exception
                  }
                  AzureQueue.Delete(bMessage);
                });

    With this change now, profiling results show that up-to 90% of time is only taken by the Azure Message delete calls. As it is good to delete message as soon as processing is done, i remove it just after "DoSomething" is finished.

    what i need now is suggestions on how to further improve performance of this function when 90% of the time is being eaten up by the Azure Queue Delete call itself? is there a better faster way to perform delete/bulk delete etc?

    with the implementation mentioned here, i get speed of close to 25 messages/sec. Right now Azure queue delete calls are choking application performance. so is there any hope to push it further.

    Does it also makes difference in performance which queue delete call am making? as of now queue has overloaded method for deleting message, one which except message object and another which accepts message identifier and pop receipt. i am using the later one here with message identifier nad pop receipt to delete message from queue.

    Let me know if you need any additional information or any clarification in question.

    Inputs/suggestions are welcome.

    Many thanks.

               
    • Edited by Omi1 Wednesday, November 5, 2014 1:46 PM added more queries
    Friday, October 31, 2014 1:26 PM

All replies

  • The first thing that came to mind was to use a parallel delete at the same time you run the work in DoSomething.  If DoSomething fails, add the message back into the queue.  This won't work for every application, and work that was in the queue near the head could be pushed back to the tail, so you'd have to think about how that may effect your workload.

    Or, make a threadpool queued delete after the work was successful.  Fire and forget.  However, if you're loading the processing at 25/sec, and 90% of time sits on the delete, you'd quickly accumulate delete calls for the threadpool until you'd never catch up.  At 70-80% duty cycle this may work, but the closer you get to always being busy could make this dangerous.

    I wonder if calling the delete REST API yourself may offer any improvements.  If you find the delete sets up a TCP connection each time, this may be all you need.  Try to keep the connection open, or see if the REST API can delete more at a time than the SDK API can.

    Or, if you have the funds, just have more VM instances doing the work in parallel, so the first machine handles 25/sec, the second at 25/sec also - and you just live with the slow delete.  If that's still not good enough, add more instances.


    Darin R.

    Friday, October 31, 2014 3:08 PM
  • Thanks Darin for reply.

    great suggestions and i tried the first one. i still end up processing message faster then it can be removed from queue.

    second one i already attempted and encountered problem which you assumed here right.

    I'll give a shot to REST API approach, keeping fingers crossed that may help pushing things further.

    More VM's are last resort, trying to get every bit of juice from one VM itself.

    will post back if i find any improvements.

    again, thanks from reply.

    -Sourabh

    Wednesday, November 5, 2014 1:50 PM
  • Hi,

    Any updates?

    Regards,
    Malar.

    Wednesday, December 3, 2014 10:09 AM