![[z/OS]](../ngzos.gif)
z/OS 应用程序的设计和性能注意事项
应用程序设计是影响性能的最重要因素之一。 使用本主题来了解性能中涉及的某些设计因素。
低劣的程序设计可以通过许多方式影响性能。 这些问题可能难以检测,因为程序可能看似执行良好,但同时会影响其他任务的性能。 以下部分中说明了特定于进行 MQI 调用的程序的若干问题。
有关应用程序设计的更多信息,请参阅 IBM MQ 应用程序的设计注意事项。
消息长度的影响
虽然 IBM MQ for z/OS® 允许消息最多容纳 100 MB 数据,但消息中的数据量会影响处理消息的应用程序的性能。 要使应用程序达到最佳性能,只发送消息中必不可少的数据。 例如,在记入银行帐户借方的请求中,可能需要从客户机传递到服务器应用程序的唯一信息是帐号和借记金额。
消息持久性的影响
系统会记录持久消息。 记录消息会降低应用程序的性能,因此应只对必不可少的数据使用持久消息。 如果消息中的数据可以在队列管理器停止或失败时废弃,请使用非持久消息。
- 发生落实
- 在同步点外获取或放置消息
- WRTHRSH 缓冲区已填满
搜索特定消息
MQGET 调用通常检索来自队列的第一条消息。 如果您使用消息和相关标识(MsgId 和 CorrelId)在消息描述符中指定特定消息,队列管理器将搜索该队列直到找到该消息。 以此方式使用 MQGET 会影响应用程序的性能,因为要查找特定消息, IBM MQ 可能必须扫描整个队列。
您可以使用 IndexType 队列属性来指定您希望队列管理器维护索引,该索引可用于提高队列上 MQGET 操作的速度。 但是,维护索引会略微降低性能,因此仅当需要使用索引时才进行生成。 可以选择构建消息标识或相关标识的索引,也可以选择不为顺序检索消息的队列构建索引。 请尝试具有许多不同的键值,而不是许多键具有相同值。 例如 Balance1、Balance2 和 Balance3,而不是三个具有 Balance 的索引。 对于共享队列,必须具有正确的 IndexType。 有关 IndexType 队列属性的详细信息,请参阅 IndexType。
要通过使用索引队列避免影响队列管理器重新启动时间,请使用 CSQ6SYSP 宏中的 QINDXBLD(NOWAIT) 参数。 借此可以完成队列管理器重新启动,而不用等待队列索引构建完成。
有关 IndexType 属性和其他对象属性的完整描述,请参阅对象的属性。
包含不同长度的消息的队列
使用与消息的预期大小相匹配的缓冲区大小获取消息。 如果您收到指示消息太长的返回码,请获取更大的缓冲区。 当以此方式进行获取失败时,所返回的数据长度是未转换的消息数据的大小。 如果在 MQGET 调用中指定 MQGMO_CONVERT,并且数据在转换期间扩展,那么它可能仍不适合缓冲区大小,在此情况下需要进一步增大缓冲区的大小。
如果发出缓冲区长度为零的 MQGET,那么它将返回消息的大小,然后应用程序可以获取此大小的缓冲区并重新发出 get 调用。 如果有多个应用程序处理队列,那么在原始应用程序重新发出 get 调用时,其他应用程序可能已处理消息。 如果偶尔具有大型消息,那么可能需要仅为这些消息获取大缓冲区,并在处理消息后释放该缓冲区。 如果所有应用程序都具有大缓冲区,那么这应有助于减少虚拟存储器问题。
同步点的频率
在同步点内发出许多 MQPUT 调用而没有将其落实的程序可能会导致性能问题。 受影响队列可能会充满当前不可用的消息,而其他任务可能在等待获取这些消息。 这在存储以及在与尝试获取消息的任务捆绑的线程方面具有影响。
- 具有 100 条短消息(小于 1 KB),或者
- 针对更大的消息 (100 KB) 具有一条消息
您可以使用 MAXUMSGS 队列管理器属性来限制任务可以在单个恢复单元内获取或放入的消息数。 有关此属性的信息,请参阅 MQSC 命令中的 ALTER QMGR 命令。
MQPUT1 调用的优点
仅在您要将单条消息放在队列上的情况下,使用 MQPUT1 调用。 如果要放置多条消息,请使用 MQOPEN 调用,后跟一系列 MQPUT 调用和单个 MQCLOSE 调用。
队列管理器可以包含的消息数
- 本地队列
队列管理器可以容纳的本地消息数基本上是页集的大小。 您最多可以具有 100 个页集(虽然建议页集 0 和页集 1 用于系统相关对象和队列)。 可以使用具有扩展格式的页集并增大页集的容量。
- 共享队列
-
共享队列的容量取决于耦合设施 (CF) 的大小。 IBM MQ 使用 CF 列表结构,其中基本存储单元是条目和元素。 各消息作为包含关联 MQMD 及其他消息数据的 1 个条目和多个元素进行存储。 单条消息消耗的元素数取决于消息的大小以及在 MQPUT 时间生效的卸载规则(对于 CFLEVEL(5))。 将消息数据卸载到 Db2® 或 SMDS 时,需要的元素更少。 卸载消息后,消息数据访问更缓慢。 请参阅性能 Supportpac MP1H 以进一步比较性能和与消息卸载关联的 CPU 开销。
影响性能的因素
性能可能意味着消息的处理速度,并且还可能意味着每条消息所需的 CPU 用量。
- 影响消息处理速度的因素
对于持久消息,最大的影响是日志数据集的速度。 日志数据集的速度取决于它们所在的 DASD。 因此,应注意将日志数据集放在使用率低的卷上以减少争用。 当每个 I/O 写入多个页面时,对 MQ 日志进行条带分割可提高日志性能。 Z High Performance Fibre (zHPF) 连接在 I/O 子系统繁忙时也能显著改善 I/O 响应时间。
当存在获取和放置消息的请求时,在请求期间会锁定对队列的访问以保留队列的完整性。 出于规划目的,请考虑对整个请求进行锁定的队列。 因此,如果放置的时间为 100 微秒,并且每秒有超过 10,000 个请求,那么可能会遇到延迟。 在实践中可能会实现比这更好的性能,但它是理想的通用规则。 可以使用不同队列来提高性能。
此问题的可能原因可以是:- 使用每个 CICS® 事务使用的公共应答队列
- 为每个 CICS 事务提供了对队列的唯一应答
- 对 CICS 区域的队列的应答以及 CICS 区域中的所有事务使用此队列。
如果必须从页集读取消息,那么与消息位于缓冲池中时相比,这些消息速度将更慢。 如果您具有的消息超过缓冲池大小,那么消息将溢出到磁盘。 因此,您需要确保缓冲池对于短期消息足够大。 如果您具有经过多个小时后处理的消息,那么它们可能会溢出到磁盘,因此应执行 get 调用,以使这些消息相比于其位于缓冲池中时速度更慢。
对于共享队列,消息的速度取决于耦合设施的速度。 物理处理器中的 CF 可能比外部 CF 速度更快。 CF 响应时间取决于 CF 的繁忙程度。 例如在 Hursley 系统上,当 CF 繁忙程度为 17% 时,响应时间为 14 微秒。 当 CF 繁忙程度为 95% 时,响应时间为 45 微秒。
如果 MQ 请求使用大量 CPU,那么这可能会影响消息的处理速度。 因为如果逻辑分区 (LPAR) 受 CPU 约束,那么应用程序将延迟,等待 CPU。
- 每条消息的 CPU 用量
一般而言,较大的消息使用较多 CPU,因此请尽量避免大型 (x MB) 消息。
从队列获取特定消息时,队列应建立索引,以使队列管理器可以直接转至消息(并因此避免可能对队列进行整体扫描)。 如果队列未建立索引,那么将从开始扫描队列来查找消息。 如果队列上有 1000 条消息,那么可能必须扫描全部 1000 条消息。 结果是许多不必要的 CPU 使用。
由于消息的加密,使用 TLS 的通道具有额外成本。
在 MQ V7 中,除了 CORRELID 或 MSGID 之外,还可以通过选择器字符串选择消息。 必须查看每条消息,因此如果队列上有许多消息,那么此操作的成本非常高昂。
应用程序执行 OPEN PUT PUT CLOSE 比执行 PUT1 PUT1 更高效。
- 在 CICS 中触发
当已触发队列的消息的消息到达率较低时,首先使用触发器比较高效。 当消息到达率为每秒 10 条以上消息时,触发第一个事务,然后由该事务处理消息并获取下一条消息(依此类推)更高效。 如果消息在短期(假设 0.1 和 1 秒之间)内未到达,那么事务结束。 在高吞吐量情况下,可能需要运行多个事务来处理消息并防止消息堆积。 对于产生的每条触发器消息,这要求放置和获取触发器消息,实际会使消息的成本加倍。
- 支持的连接数或并发用户数
每个连接在队列管理器内使用虚拟储存器,因此并发用户越多,所使用的存储器就越多。 如果需要超大缓冲池和大量用户,那么您可能会受制于虚拟存储器,并且可能需要减小缓冲池的大小。
如果使用安全性,那么队列管理器会将信息长期高速缓存在队列管理器中。 队列管理器内使用的虚拟存储量会受影响。
CHINIT 最多可以支持大约 10,000 个连接。 这受到虚拟存储器的限制。 如果连接使用更多存储空间(例如,通过 TLS 使用),则每个连接的存储空间会增加,这意味着 CHINIT 可支持的连接数会减少。 如果您要处理大消息,那么这些消息将需要更多存储空间以用于 CHINIT 中的缓冲区,因此 CHINIT 可支持的消息数会减少。
与远程队列管理器的连接比客户机连接更高效。 例如,每个 MQ 客户机请求需要两个网络流(一个用于请求,另一个用于响应)。 利用与远程队列管理器的通道,在返回响应之前,网络上可能有 50 次发送。 如果您考虑的是大型客户机网络,那么在分布式设备上使用集中器队列管理器并有一条出入于集中器的通道可能更高效。
影响性能的其他因素
日志数据集的大小应至少为 1000 个柱面。 如果日志小于此大小,那么检查点活动可能过于频繁。 在繁忙系统上,检查点通常应为每 15 分钟或更长时间,在超高吞吐量情况下,可能小于此时间。 当出现检查点时,将会扫描缓冲池并将“旧”消息和已更改页面写入到磁盘。 如果检查点过于频繁,那么这会影响性能。 LOGLOAD 的值也可影响检查点频率。 如果队列管理器异常结束,那么在重新启动时,可能必须回读至 3 个检查点。 最佳检查点时间间隔是在采用检查点时的活动与队列管理器重新启动时可能需要读取的日志数据量之间达到平衡。
启动通道时,将会招致重大开销。 通常最好启动通道并使其保持连接,而不是频繁启动和停止通道。