多订阅导致IBM MQ集群主题写入严重缓慢的原因排查
问题分析与解决方案
核心原因拆解
MQ的Direct类型集群主题在处理多订阅时,本地订阅的磁盘写入操作(即使是非持久化消息)会因EFS的网络IO延迟阻塞消息分发流程,进而引发系统队列堆积,具体逻辑如下:
- 当发布非持久化消息到Direct集群主题时,MQ需要将消息分发给所有匹配的订阅:
- 对于本地订阅:无论消息是否持久化,只要订阅指向本地队列,MQ必须将消息写入该本地队列(本地队列默认依赖磁盘存储,这里用EFS)
- 对于代理订阅(集群内或跨第三方QM的):非持久化消息的转发可在内存中完成,无需落地磁盘,除非代理订阅被配置为持久化
- EFS作为网络存储,虽然吞吐量未达阈值,但单IO操作的延迟远高于本地磁盘。在高流量(每秒10条)场景下,每条消息都要同步等待EFS的写入完成,会占用MQ的消息分发线程,导致集群转发、跨QM转发的消息无法及时处理,最终堆积在
SYSTEM.CLUSTER.TRANSMIT.CLUSNAME.QM2(集群传输队列)和SYSTEM.INTER.QMGR.PUBS(跨QM发布转发队列)中。 - 移除第二个QM的本地订阅后,MQ无需再处理EFS的本地队列写入,消息分发线程不再被阻塞,代理订阅的内存级转发可以高效完成,堆积自然清除。
验证手段
- 查看MQ错误日志
AMQERR01.LOG,检查是否存在I/O operation delayed或类似的磁盘等待警告 - 用
runmqsc执行以下命令,查看本地队列的写入等待情况:
若DIS QSTATUS(LOCAL_QUEUE_NAME) TYPE(QUEUE) PUTWPUTW(等待PUT的线程数)持续偏高,说明存在IO阻塞
优化建议
- 测试场景下,高流量测试时临时移除本地订阅,避免不必要的磁盘写入
- 若必须保留本地订阅,可将本地队列配置为内存队列(注意:内存队列重启后数据丢失,仅适用于测试),通过
ALTER QLOCAL(QUEUE_NAME) STORAGE(MEMORY)命令配置 - 调整EFS的性能模式:切换到Max I/O模式,相比默认的General Purpose模式,能降低高并发下的IO延迟
- 检查代理订阅的属性,确保非持久化消息的代理订阅未被配置为持久化:
若DIS SUB(SUB_NAME) PERSISTENCEPERSISTENCE为PERSISTENT,可修改为NONPERSISTENT
内容的提问来源于stack exchange,提问作者simonalexander2005
相关产品推荐
相关产品推荐

