【发布时间】:2020-08-23 20:05:20
【问题描述】:
我有一个使用 IBM MQ 传输文件的项目。有10000个客户端和一个数据中心。最大的文件大小几乎是 8MB。 MQ 集群包含三个 MQ 管理器,它们位于不同的 Windows 服务器上。每个 MQ 管理器有 5 个客户端通道和 5 个数据中心通道。有两种情况可供测试。在每种情况下,客户端被平均分配给 MQ 管理器。在这些情况下,不要丢失任何文件是最重要的。
Case 1:
Every client send 50 files to data center at the same time. The files size are between 150KB to 5MB.
In this case, the sum of file size one client send is almost 80MB.
Case 2 :
Data center send the 10 identical files to every client at the same time. In this case, I create a topic named `myTopic` and 10000 clients subscribe this topic. Data center send 10 identical files to the topic.
MQ Manger 的负载很重。我已经在 IBM MQ 中设置了一些属性:
Queue Manager:
Max handles: 100000
Maximum message length: 100MB
Max channels: 10000
Max channels: 10000
有没有什么属性可以提高性能?
5/11 更新:
首先,我修改了上面案例2的情况。我有一个具有 4 核 CPU 和 32G RAM 的数据中心服务器。我用4个客户端服务器模拟10000个客户端,每个客户端服务器有4核CPU和16G RAM。
在案例 1 中,1000 个客户端向数据中心发送文件大约需要 37 分钟。数据中心从 2000 个客户端接收文件时,数据中心服务器内存不足。我发现有 20G 内存用于缓冲区/缓存。这是我用来接收文件的java代码:
try {
String filePath = ConfigReader.getInstance().getConfig("filePath");
MQMessage mqMsg = new MQMessage();
mqMsg.messageId = CMQC.MQMI_NONE;
mqMsg.correlationId = CMQC.MQCI_NONE;
mqMsg.groupId = CMQC.MQGI_NONE;
int flag = 1;
while (true) {
try {
MQQueueManager queueManager = new MQQueueManager("QMGR1");
int option = CMQC.MQTOPIC_OPEN_AS_SUBSCRIPTION | CMQC.MQSO_DURABLE;
MQTopic subscriber = queueManager.accessTopic("", "myTopic", option, null, "datacenter");
subscriber.get(mqMsg);
if (mqMsg.getDataLength() != 0) {
String fileName = filePath + "_file" + flag + ".txt";
byte[] b = new byte[mqMsg.getDataLength()];
mqMsg.readFully(b);
System.out.println("Receive " + fileName + ", complete time: " + System.currentTimeMillis());
Path path = Paths.get(fileName);
System.out.println("Write " + fileName + ", start time: " + System.currentTimeMillis());
Files.write(path, b);
System.out.println("Write " + fileName + ", complete time: " + System.currentTimeMillis());
flag++;
}
} catch (MQException e) {
// e.printStackTrace();
if (e.reasonCode != 2033) {
e.printStackTrace();
}
} finally {
mqMsg.clearMessage();
mqMsg.messageId = CMQC.MQMI_NONE;
mqMsg.correlationId = CMQC.MQCI_NONE;
mqMsg.groupId = CMQC.MQGI_NONE;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我使用字节数组读取消息并将其写入磁盘。是不是字节数组不释放内存,占用20G内存?
在情况 2 中,我发现如果我向 myTopic 发送一个 5MB 的文件,在 MQ manager01 上拥有 1000 个订阅者,MQ manager01 需要花费大量时间与集群成员同步。 MQ 服务器上的磁盘非常繁忙。还有一个问题:有时我只需要 7 秒来发送一个 5MB 的文件,有时需要 90 秒。这是我发送文件的 java 代码:
try {
MQQueueManager queueManager = new MQQueueManager("QMGR1");
MQTopic publisher = queueManager.accessTopic("myTopic", "", CMQC.MQTOPIC_OPEN_AS_PUBLICATION,
CMQC.MQOO_OUTPUT);
System.out.println("---- start publish , time: " + System.currentTimeMillis() + " ----");
publisher.put(InMemoryDataProvider.getInstance().getMessage("my5MBFile"));
System.out.println("---- end publish , time: " + System.currentTimeMillis() + " ----");
publish.getPublisher().close();
} catch (MQException e) {
System.out.println("threadNum: " + publish.getThreadNo() + " publish error");
if (e.reasonCode != 2033) {
e.printStackTrace();
}
}
【问题讨论】:
-
如果与客户端的网络连接是限制因素,则通道上的压缩会有所帮助。这只是一个猜测,因为您还没有描述现在您正在尝试改进的性能是什么,或者当前的瓶颈在哪里。
-
同意@JoshMc 压缩——它使用的 CPU 很少成为消息传递的瓶颈。多少个CPU?服务器的磁盘性能是多少? NVME 存储将为您带来巨大的提升,而 RAID SSD 紧随其后。
-
你应该在这个网站上试试,这就是他们所做的一切:mqseries.net
-
您正在执行一个没有延迟的 get 循环,据我所知,每次都打开一个与队列管理器的新连接,我确信这应该在某个时候失败,你不接收和 MQ 异常?最好在循环之前创建与队列管理器的连接并订阅主题 1 次,在循环中您只需执行获取并添加等待间隔,等待是 MQ 之前等待队列上的消息的时间它返回 2033,只要它出现在队列中,您仍然会收到该消息。
-
能否显示主题对象和持久模型队列?
标签: websphere ibm-mq file-transfer large-files large-data-volumes