ASG
IBM
Zystems
Cressida
Icon
Netflexity
 
  MQSeries.net
Search  Search       Tech Exchange      Education      Certifications      Library      Info Center      SupportPacs      LinkedIn  Search  Search                                                                   FAQ  FAQ   Usergroups  Usergroups
 
Register  ::  Log in Log in to check your private messages
 
RSS Feed - WebSphere MQ Support RSS Feed - Message Broker Support

MQSeries.net Forum Index » IBM MQ API Support » Performance problem using Get

Post new topic  Reply to topic Goto page 1, 2  Next
 Performance problem using Get « View previous topic :: View next topic » 
Author Message
palaslet
PostPosted: Tue Mar 15, 2011 5:48 am    Post subject: Performance problem using Get Reply with quote

Newbie

Joined: 15 Mar 2011
Posts: 9

Hi all,

I'm currently developing an application to fetch messages from IBM MQ, do some custom validation and parsing, and then putting the result into a database.

Traffic is quite high, and it's not unusual to get 2000 messages in one go from the external system posting messages to the queue. The system needs to put these messages as fast as possible into the database or else the backlog will increase infinite.

When fetching messages from the queue I can see that the first 50 or so goes fast (15 ms pr message or less), then the system slows down to about 5s pr message (I'm sure you can see that this behavior is problematic).

It's probably worth mentioning that I don't want to have many messages in memory at any time as that's not very reliable in case of failure for any reason (This is actually a customer demand, and I can't do anything about it).

I've tried several different methods, but it all comes out the same. 50 messages super fast and then the rest takes 5 seconds per message.

EDIT: I can download 2000 messages in 14 seconds if I put all of them in memory, but if I batch them in any way to reduce the number of messages in memory) it seems breaking the continuous "get-ing" makes the server down-prioritize my connection, and after about 50 or so messages, I'm down to 5 seconds per message.

Please help!


Last edited by palaslet on Tue Mar 15, 2011 5:54 am; edited 1 time in total
Back to top
View user's profile Send private message
Mr Butcher
PostPosted: Tue Mar 15, 2011 5:53 am    Post subject: Reply with quote

Padawan

Joined: 23 May 2005
Posts: 1716

help us to help you....

what plattform
what mq level
what programming language
do you mind to show the code / loop which is resposible for the mqget
how often do you commit
what database
..... more to come
_________________
Regards, Butcher
Back to top
View user's profile Send private message
palaslet
PostPosted: Tue Mar 15, 2011 6:02 am    Post subject: Reply with quote

Newbie

Joined: 15 Mar 2011
Posts: 9

Sorry...

Platform: Windows
MQ Level: ???? What do you mean by that?
Language: C#

I've tried several different commit configurations, but it doesn't seem to have any effect.


Code:

List<WebSphereMQMessage> uncommittedMessages = new List<WebSphereMQMessage>();
Boolean hasMoreMessages = true;
while (hasMoreMessages)
{
   using (MQQueue mqQueue = mqQMgr.AccessQueue(connectionParameters.QueueName, MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING))
   {
      MQGetMessageOptions mqGetMsgOpts = new MQGetMessageOptions();
      mqGetMsgOpts.Options |= MQC.MQGMO_NO_WAIT;
      mqGetMsgOpts.Options |= MQC.MQGMO_NO_SYNCPOINT;
      for (Int32 i = 0; i < 25; i++)
      {
         WebSphereMQMessage mqMsg = null;
         try
         {
            mqMsg = new WebSphereMQMessage();
            mqMsg.CorrelationId = MQC.MQCI_NONE;
            mqMsg.MessageId = MQC.MQMI_NONE;
            mqQueue.Get(mqMsg.InnerMessage, mqGetMsgOpts);
            uncommittedMessages.Add(mqMsg);
         }
         catch (MQException mqEx)
         {
            if (mqEx.ReasonCode == MQC.MQRC_NO_MSG_AVAILABLE)
            {
               hasMoreMessages = false;
               break;
            }
         }
      }
   }
   if (uncommittedMessages.Count > 0)
   {
      // Add messages to database
      foreach (WebSphereMQMessage mqMsg in uncommittedMessages)
      {
         if (newMessageReceivedCallback == null || newMessageReceivedCallback(mqMsg))
            messages.Add(mqMsg);
      }
      uncommittedMessages.Clear();
      mqQMgr.Commit();
   }
}
Back to top
View user's profile Send private message
zpat
PostPosted: Tue Mar 15, 2011 6:39 am    Post subject: Reply with quote

Jedi Council

Joined: 19 May 2001
Posts: 5866
Location: UK

Use MQ syncpointing to protect data from memory crashes. Limiting the number in memory is not as good. Syncpoints should not be too large, I tend to suggest no more than 200 uncomitted messages in a single unit of work, although most queue managers allow up to 10,000.
Back to top
View user's profile Send private message
Mr Butcher
PostPosted: Tue Mar 15, 2011 6:44 am    Post subject: Reply with quote

Padawan

Joined: 23 May 2005
Posts: 1716

just a quick finding.

if you mqget with MQGMO_NO_SYNCPOINT, there is nothing you can commit, as you get the message outside the UOW.

mq level is the version. e.g. 6.0.1.13 or whatever. type "dspmqver" on the server, it should show you the version.
_________________
Regards, Butcher
Back to top
View user's profile Send private message
palaslet
PostPosted: Tue Mar 15, 2011 6:46 am    Post subject: Reply with quote

Newbie

Joined: 15 Mar 2011
Posts: 9

Thanks for the suggestion.

How do I best implement syncpointing in C#?

I'm somewhat unfamiliar with the MQ inner functionality and all its possibilities. Earlier we were dealing with much less data and thus the perfomance issue never occured. Simple GET -> PARSE -> COMMIT sequence was sufficient. Lately we are designing one of the largest systems in its class, and some of the customers want to use MQ to integrate with us.
Back to top
View user's profile Send private message
zpat
PostPosted: Tue Mar 15, 2011 6:53 am    Post subject: Reply with quote

Jedi Council

Joined: 19 May 2001
Posts: 5866
Location: UK

Single phase commit is very easy. Simply change the MQGET to have the option MQGMO_SYNCPOINT. After a certain number of these gets (and when the data has been processed successfully) you can issue the MQCMIT call.
Back to top
View user's profile Send private message
palaslet
PostPosted: Tue Mar 15, 2011 7:03 am    Post subject: Reply with quote

Newbie

Joined: 15 Mar 2011
Posts: 9

I'm sorry, but that won't help me. I'll try to be more accurate in my problem description:

I need to:
1. fetch a message from MQ
2. Validate and transform it
3. Put it into the database (Oracle)
4. commit the message in MQ

I can batch the messages from MQ before putting them into the database to improve speed. The problem is when when the batch is full (lets say 200) and I'm sending the batch of to parsing and the program returns after parsing a few seconds later, the speed of GET is down to 5 seconds pr message. And thats with no commit and no syncpoint (I just removed them to be sure nothing was interfering with performance)
Back to top
View user's profile Send private message
palaslet
PostPosted: Tue Mar 15, 2011 7:06 am    Post subject: Reply with quote

Newbie

Joined: 15 Mar 2011
Posts: 9

Here's a better code example with some test results:

1. This code fetches 200 messages in 10 seconds.
Code:

using (MQQueue mqQueue = mqQMgr.AccessQueue(connectionParameters.QueueName, MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING))
{
   List<WebSphereMQMessage> uncommittedMessages = new List<WebSphereMQMessage>();
   Boolean hasMoreMessages = true;
   Console.WriteLine(DateTime.Now.ToString("hh:MM:ss.fffff") + " start fetcing");
   while (hasMoreMessages)
   {
      MQGetMessageOptions mqGetMsgOpts = new MQGetMessageOptions();
      mqGetMsgOpts.Options |= MQC.MQGMO_NO_WAIT;
      mqGetMsgOpts.Options |= MQC.MQGMO_NO_SYNCPOINT;
      for (Int32 i = 0; i < 25; i++)
      {
         WebSphereMQMessage mqMsg = null;
         try
         {
            mqMsg = new WebSphereMQMessage();
            mqMsg.CorrelationId = MQC.MQCI_NONE;
            mqMsg.MessageId = MQC.MQMI_NONE;
            mqQueue.Get(mqMsg.InnerMessage, mqGetMsgOpts);
            uncommittedMessages.Add(mqMsg);
         }
         catch (MQException mqEx)
         {
            if (mqEx.ReasonCode == MQC.MQRC_NO_MSG_AVAILABLE)
            {
               hasMoreMessages = false;
               break;
            }

            ReasonCodes rc = new ReasonCodes();
            if (mqEx.ReasonCode == MQC.MQRC_FORMAT_ERROR)
            {
               Exception ex = new Exception(rc[mqEx.ReasonCode]);
               ex.Data.Add("message", mqMsg);
               throw ex;
            }

            throw new Exception(rc[mqEx.ReasonCode]);
         }
      }
      //if (uncommittedMessages.Count > 0)
      //{
      //    foreach (WebSphereMQMessage mqMsg in uncommittedMessages)
      //    {
      //        if (newMessageReceivedCallback == null || newMessageReceivedCallback(mqMsg))
      //            messages.Add(mqMsg);
      //    }
      //    uncommittedMessages.Clear();
      //}
   }
   Console.WriteLine(DateTime.Now.ToString("hh:MM:ss.fffff") + " end fetcing");
}


This is the resulting output in console:
Code:

03:03:20.52606 start fetching
03:03:30.94799 end fetching


2 If I uncomment the part handling the messages, the performance drops to 200 messages in ca 14 minutes 40 seconds
Code:

03:49:23.66249 start fetching
04:04:05.72180 end fetching


The "newMessageReceivedCallback" method will do a 20 ms sleep to simulate validation and paring into database. It shouldn't add more than 4 seconds to the total time
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Tue Mar 15, 2011 7:18 am    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

how big are those messages?
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
palaslet
PostPosted: Tue Mar 15, 2011 7:29 am    Post subject: Reply with quote

Newbie

Joined: 15 Mar 2011
Posts: 9

That varies greatly as they are messages to customs authorities around the world describing the goods they want to import/export. One message can have 1 goods line, or 1000 goodslines depending of the nature of the goods.

So the messages can vary from 1KB to 100 KB or even more.

For the test described above, I've created a random message generator that puts 200 random messages of 3-4KB on the queue.
Back to top
View user's profile Send private message
palaslet
PostPosted: Tue Mar 15, 2011 7:30 am    Post subject: Reply with quote

Newbie

Joined: 15 Mar 2011
Posts: 9

Mr Butcher wrote:

mq level is the version. e.g. 6.0.1.13 or whatever. type "dspmqver" on the server, it should show you the version.



Name: WebSphere MQ
Version: 6.0.0.0
CMVC level: p000-L050519
BuildType: IKAP - (Production)
Back to top
View user's profile Send private message
fjb_saper
PostPosted: Tue Mar 15, 2011 1:20 pm    Post subject: Reply with quote

Grand High Poobah

Joined: 18 Nov 2003
Posts: 20756
Location: LI,NY

palaslet wrote:
Mr Butcher wrote:

mq level is the version. e.g. 6.0.1.13 or whatever. type "dspmqver" on the server, it should show you the version.



Name: WebSphere MQ
Version: 6.0.0.0
CMVC level: p000-L050519
BuildType: IKAP - (Production)

Upgrade soonest. That version (vanilla 6.0) was not one of the best. You should be at 6.0.2.10 or above, or at V7.0.1.4.

It is entirely possible that you will not see the problem at V 6.0.2.10
_________________
MQ & Broker admin
Back to top
View user's profile Send private message Send e-mail
gbaddeley
PostPosted: Tue Mar 15, 2011 3:03 pm    Post subject: Re: Performance problem using Get Reply with quote

Jedi Knight

Joined: 25 Mar 2003
Posts: 2538
Location: Melbourne, Australia

palaslet wrote:
When fetching messages from the queue I can see that the first 50 or so goes fast (15 ms pr message or less), then the system slows down to about 5s pr message (I'm sure you can see that this behavior is problematic).


It looks like you are hitting some sort of resource limitation or contention, most likely in Windows managing all the processes and workload, such as memory, CPU.

MQ does not normally behave like this - it should be fast all the time.
_________________
Glenn
Back to top
View user's profile Send private message
palaslet
PostPosted: Wed Mar 16, 2011 12:27 am    Post subject: Reply with quote

Newbie

Joined: 15 Mar 2011
Posts: 9

I totally agree. The odd thing is that I can reproduce this both locally on an inhouse MQ server, and at the customer at their MQ server.

If it's worth anything I'll try to create a standalone console program to reproduce it and get the tech team to poke a hole in the firewall so any of you can run it and play around.

Just tell me to, and I'll start the coding.

Thanks for all your help so far!
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic  Reply to topic Goto page 1, 2  Next Page 1 of 2

MQSeries.net Forum Index » IBM MQ API Support » Performance problem using Get
Jump to:  



You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
Protected by Anti-Spam ACP
 
 


Theme by Dustin Baccetti
Powered by phpBB © 2001, 2002 phpBB Group

Copyright © MQSeries.net. All rights reserved.