We were asked by some to give some tips on performance when using MQ on z/OS.
Lyn Elkins and I came up with this list. It is not complete but reflect some of what we have seen at customer sites.
Avoid multi hops
We have seen a broker application which had a flow got from a queue, processed the data, put to another queue. Another flow got the data .. etc. There were 10 hops in total
- If this was using persistent messages - and each commit took 2 ms - then the total time in commit activity along was 20ms.
- A lot of CPU was spent parsing the XML data into the internal tree within memory, , then writing the internal tree into XML
- Lots of gets and puts - all of which took CPU time
So try to do as much processing in one unit of work as possible,
CICS triggering is fine for low transaction rates - up to 10 messages a second.
With triggering a messages is put to the trigger queue, the trigger monitor has to get the message and start the transaction. If the input rate is 1000 messages a second - this is an additional 1000 messages a second being put and got, as well as the overhead of starting the transactions
A common pattern is to use long running transactions as follows
- Use trigger first to start the first transaction
- The CICS transaction does an MQINQ to get the curdepth and the number of input handles.
- Have some logic to decide if more application instances need to be started, such as if curdepth > 50 and number of input handles < 10 then start a new transaction
- Have the business logic.
- After a certain number of messages processed- perhaps 1000 or 10,000 messages, the transaction ends.
Having the transaction end and be restarted means that CICS can start the transaction in the optimum system, for example on a CICS region in a different LPAR. This provides workload balancing. Also you you get the CICS Monitoring data produced when the transaction ends.
Consider your use of message persistence
We have seen cases where persisent messages are used for inquiry type applications.
It is common for persistent messages to be processed within syncpoint. So check to see if you are processing non persistent messages within syncpoint, or persistent messages out of syncpoint. These are both valid but check.
Size the resources you need
Bufferpools and pagesets for private queues, CF for shared queues, Shared message data sets for shared queues. Making sure the capacity is there, or that expansion capability can be turned on.
If your system is short of CPU and you find MQ slow - fix the CPU problem first.
Make sure your buffer pools are big enough to keepk short lived message in the buffer pool.
Monitor the MVS CF stats to make sure MQ is getting good response time.
Check the performance of the resources
Location of underlying resources can be an issue. This is often overlooks as most I/O subsystems now claim you do not have to worry about this. In practice, we have found for high volume systems this can be an impediment to making the throughput required. This may be as simple as making sure that the high level qualifier names are different so the I/O requests get distributed over different controllers and DASD ( or chaning the SMS definitions). Something as simple the physical separation of the MQ logs, and their corresponding archive files, from one volume to multiple volumes, so they did not interact has made a huge difference in performance.
If heavily dependent on message persistence, make sure the MQ log datasets are striped across 4 volumes. More than 4 has not been shown to help. it can be a real performance booster for logging - perhaps doubling the throughput
not quite performance but..
If using MQ shared queues and CICS, make sure the CICS MQCONN definition points to the queue sharing group name.