MQ is resilient and works even through applications are badly written. The side effects of badly designed application are usually high CPU costs, and extended transaction times.
Today I was contacted about two customer problems, and I thought they were interesting and worth socializing
Problem 2: We want to increase the maximum Uncommitted Messages (MaxUncomittedMsgs) what is the impact?
Having a large number of messages in a batch can give you significant increase in throughput.
Any gets trying to get messages within the unit of work will get higher cost (and duration) as the program tries to get messages which are not available.
Having more than 1 message per Unit of work ( eg MQPUT, COMMIT) can give improved throughput.
Consider an MQPUT taking 1 ms, and a commit taking 10 ms. MQPUT, COMMIT, MQPUT, COMMIT takes 1+10+1+10 = 22 ms. This gives a message rate of ( 2* 1000/22 or 91 messages a second
If you do MQPUT, MQPUT,COMMIT this takes 1+1+10 = 12 ms, This is much faster and a message rate of 2 * 1000/12 = 167 a second.
With channels the BATCHSZ controls how many messages per batch are processed. 50 is good for many people, but we have seen benefits of batch size if 1000 for long distances.
This is only half the story. The other half is the MQGET.
If there are many messages on the queue, MQGET can get the first message.
If there are few messages on the queue, and the MQGET is trying to get a message which has not been committed, then the logic is like
Get the next message - this cannot get it, because it has not been committed, loop. Eventually there are no more messages and the MQGET returns no_message_found. If MaxUncomittedMsgs is set to 10000, then the get may attempt to get up to 10000 messages.
If a successful get takes 1ms, MQGET,COMMIT takes 11 ms - or a rate of 91 a second
MQGET,MQGET, Commit takes 12 ms .. or a rate of 167 messages a second.
If an unsuccessful get takes 0.1 ms and there are currently 1000 messages in a unit of work, then it will take 100 ms to get back no message found.
So an MQGET (successful) + MQGET(no message found) commit, takes 1+ 100 + 10 = 111. This is 9 messages a second.
Is this it? No- most performance answers have "it depends"
Consider an application does
Do I = 1 to N
DB2 UPDATE table
Having N as a large number, for example 1000 will give improved throughput in MQ, but may impact DB2.
Any DB2 updates will only be committed when the COMMIT happens. Having a long COMMIT time can cause
- Locks are held for longer in DB2
- You can get deadlocks when threads interact. Thread 1 updates record 1 and record2. Thread 2 update record 2 and wants to update record 1
So what do we recommend? This is tough. For MQ and database applications the maximum number of updates per commit might be 10. For channels, which are just MQ, 1000 messages per batch may be OK - but 50 may be better.