【问题标题】:IBM Websphere MQ Latency for storing persistent messages .NET clientIBM Websphere MQ Latency 用于存储持久消息 .NET 客户端
【发布时间】:2018-06-25 06:50:20
【问题描述】:

MQ服务器收到Put()请求时,哪些因素会影响消息的存储?以下是潜在因素:

1) 在内存中缓存消息一段时间,或者

2) 当收到一定数量的消息时

3) 当收到一定字节阈值的消息时

4) MQ 服务器为每条消息立即保存。

更新

也就是说,当Put()返回时,消息是保存到硬盘还是缓存中,取决于以上因素?

任何信息和官方文档的链接将不胜感激。

下面是一个使用 Put() 的简单场景。

     void PutMessages()
    {
         Open(ConnectionMode.Write);

            // putting messages continuously
            for (int i = 1; i <= numberOfMsgs; i++)
            {
                PutMessage(GetMessageInBytes(i));
            }

            queue.Close();
            queueManager.Disconnect();          
    }

    void PutMessage(byte[] messageString)
    {

        // creating a message object
        message = new MQMessage();
        message.Write(messageString);
        message.Format = MQC.MQFMT_STRING;
        message.CharacterSet = 1208;// IbmUtf8Encoding;
        message.Persistence = MQC.MQPER_PERSISTENT;

        var options = new MQPutMessageOptions
        {
            Options = false ? MQC.MQPMO_SYNCPOINT : MQC.MQPMO_NO_SYNCPOINT
        };

        queue.Put(message, options);            

    }

    public void Open(ConnectionMode connectionMode)
    {
        var connectionSettings = new Hashtable
        {
            {MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED },
            {MQC.CONNECT_OPTIONS_PROPERTY, MQC.MQCNO_RECONNECT }
        };

        int openOptions = 0;

        switch (connectionMode)
        {
            case ConnectionMode.Read:
                openOptions = MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING;
                break;
            case ConnectionMode.Write:
                openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING;
                break;
        }
        queueManager = new MQQueueManager(queueManagerName);
        queue = queueManager.AccessQueue(queueName, openOptions);
    }


    public enum ConnectionMode
    {
        Read,
        Write
    }

【问题讨论】:

  • 持久消息总是在 PUT 返回应用程序之前写入磁盘。持久化意味着消息被持久化到磁盘。如果 put 在同步点下完成,则写入磁盘发生在 COMMIT 而不是 PUT 时,如果 COMMIT 返回,则表示数据已写入磁盘。 MQ 当然是依靠底层操作系统和存储来准确报告数据已写入磁盘,并利用操作系统提供的写入函数来确保数据不会缓存在内存中。列表中的 #1 - #3 与持久消息无关。
  • 我想找出持久消息的延迟。可能是在 PUT 返回后,消息可能在存储到硬盘之前已保存到缓存几毫秒。我找不到来自 IBM 的相关文档。
  • 如果消息是持久的,put 只会在 MQ 确定已写入磁盘后返回,例如在 linux 上,MQ 使用O_DIRECT 标志打开文件。在 MQ 控制之外,操作系统可能会说它已写入磁盘但实际上并未执行,或者底层 SAN 存储阵列可能会说已写入磁盘但未执行此操作,但在这些情况下,操作系统和存储阵列通常会缓存在电池备份内存中,他们知道有足够的电量在发生电源故障时将缓存刷新到磁盘,但这一切都在 MQ 控制之外。
  • 我问的原因是它可能会延迟几毫秒来保存消息以避免通过 MQ 服务器逻辑影响性能,而不是保存每条消息。这发生在 RabbitMq 上。请看stackoverflow.com/questions/49546274/…
  • IBM MQ 不这样做。我正在尝试为您找到链接的引用,但 IBM 一直坚持认为它可以确保消息传递,并且在 PUT(或 COMMIT)调用返回应用程序之前,它会等到写入提交到磁盘。如果应用程序得到了良好的响应,那么它就被写入了。

标签: .net ibm-mq


【解决方案1】:

在 IBM MQ v9 知识中心页面“Application design and performance considerations”中有这两个说法:

将持久消息放在同步点下

应将持久消息放在同步点下并获取。这是 因为当在同步点之外获取持久消息时,如果 获取失败,应用程序无法知道是否 消息是否已从队列中获取,以及是否,如果 消息已得到,然后它也已丢失。当得到 同步点下的持久消息,如果任何失败, 事务回滚,持久消息不丢失 因为它还在队列中。同样,当把持久 消息,将它们放在同步点下。放置和放置的另一个原因 在同步点下获取持久消息是持久的 IBM MQ 中的消息代码针对同步点进行了高度优化。所以放 在同步点下获取持久消息比放置更快 并在同步点之外获取持久消息。

但是,在外部放置和获取非持久消息会更快 同步点,因为 IBM MQ 中的非持久性代码针对 在同步点之外。 放置和获取持久性消息 以磁盘速度运行因为持久消息被持久保存到 但是,放置和获取非持久消息 CPU 速度,因为不涉及磁盘写入,即使在 使用同步点。

如果应用程序正在获取消息并且事先不知道 无论它们是否持久,转基因选项 可以使用 MQGMO_SYNCPOINT_IF_PERSISTENT。


来自 IBM 的 Chris Frank 在Capitalware's MQ Technical Conference v2.0.1.6 发表了题为 More Mysteries of the IBM MQ Distributed Logger, 在第 87 页上的幻灯片“如果我不使用事务怎么办?(2)”状态:

  • 将此与不使用同步点进行对比:
    • 每个 MQPut 都会导致至少一次物理写入日志文件
      • 在此期间将阻止推杆应用程序

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    • 2011-09-07
    • 1970-01-01
    • 2016-12-14
    • 1970-01-01
    • 2018-01-22
    • 1970-01-01
    相关资源
    最近更新 更多