【问题标题】:worst latency for single message单条消息的最差延迟
【发布时间】:2019-07-20 03:09:53
【问题描述】:

我需要构建一个实时低延迟的消息传递系统。

我阅读了 ZeroMQ 指南,因为我的要求 ROUTER-DEALER 模式完全匹配。我围绕它构建了系统,它运行良好。但是当我进行性能测试时,我发现 ZeroMQ 延迟非常高。

libzmq 版本:4.2.5

./local_lat  tcp://127.0.0.1:5555 1 1000
./remote_lat tcp://127.0.0.1:5555 1 1000

message size:       1 [B]
roundtrip count: 1000
average latency:   26.123 [us]

当消息数很高时,ZeroMQ 的性能很棒,但是当相同的消息数为 1 时,延迟非常高。

./local_lat  tcp://127.0.0.1:5555 1 1
./remote_lat tcp://127.0.0.1:5555 1 1

message size:      1 [B]
roundtrip count:   1
average latency: 506.500 [us]

我仍然不相信我将 ZeroMQ 指南中的 PUB-SUB 示例修改为 ROUTER-DEALER 并添加了时间戳并再次测试。还有延迟真的很高。这使得 ZeroMQ 无法使用。我同意,当消息量很大时,没有什么可以击败 ZeroMQ,但是对于即使单个消息 ZeroMQ 失败,延迟也很关键的系统。

注意:我也运行了 PUB-SUB 示例,它显示了相同的延迟数据

发件人.cpp

 #include <zmq.hpp>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <sys/time.h>

int main () {

    //  Prepare our context and publisher
    zmq::context_t context (1);
    zmq::socket_t publisher (context, ZMQ_ROUTER);
    publisher.bind("tcp://*:5556");

    //wait for peer to connect
    //once connected store the identity to send message later
    zmq::message_t identity,m;
    publisher.recv(&identity);//identity
    publisher.recv(&m);//message
    sleep(1);//sleep to set up connections
    struct timeval timeofday;
    int i=1;//no of messages to send
    while (i) {
      zmq::message_t id,message("10101",5);
      id.copy(&identity);
        gettimeofday(&timeofday,NULL);
    publisher.send(id,ZMQ_SNDMORE);
        publisher.send(message);

    std::cout << timeofday.tv_sec << ", " << timeofday.tv_usec << std::endl;
        usleep(1);
    --i;
    }
    return 0;
}

reciever.cpp

#include <zmq.hpp>
#include <iostream>
#include <sys/time.h>

int main (int argc, char *argv[])
{
    zmq::context_t context (1);

      zmq::socket_t subscriber (context, ZMQ_DEALER);
       subscriber.setsockopt(ZMQ_IDENTITY,"1",1);
       subscriber.connect("tcp://localhost:5556");

    struct timeval timeofday;
    subscriber.send(" ",1);
    int update_nbr;
    int i=1;
    for (update_nbr = 0; update_nbr < i; update_nbr++) {

        zmq::message_t update;

        subscriber.recv(&update);

    gettimeofday(&timeofday,NULL);
        std::cout << timeofday.tv_sec << ", " << timeofday.tv_usec << std::endl;
    }
    return 0;
}

发送方输出

1562908600, 842072

接收器输出

1562908600, 842533

如您所见,大约需要 400 毫秒。

有什么办法可以减少延迟?

【问题讨论】:

  • 您是否介意添加一份来自实时系统详细规范文档的副本或引用,实际设计目标是什么,定义可接受的消息传递延迟范围(对于最坏情况条件和其他工作负载信封) - 即,在原始实时系统详细规范文档中实际设置了对此类延迟范围的明确要求和/或在实施此类要求的要求中定义了哪些其他设计方面的约束实时系统行为?
  • @user3666197 不,我不能提供任何文件。重要的是消息应该以尽可能低的延迟从模块 A 流向 B。这是一个对时间非常敏感的应用程序。无论什么延迟都在这里巨大的。当消息量很大时,系统工作得非常好。问题只有当有单个消息时
  • 问题很明确 - 不是提供“文档”,而是引用系统规范在要求中定义的消息传递延迟量(有多少 [us] 在保证实时系统,运行稳定并符合 RTS-DSpec 文档中的定义(更重要的是,当它是“一个非常时间敏感的应用程序”时 - 系统详细规范中的确切要求文档定义,这种延迟在规范内是什么,什么不是)。“没有目标,实际上任何道路都可能适合......”
  • 这里到底有什么不清楚的地方? .我说进程 A 向进程 B 发送消息。收到 B 的消息大约需要 400 毫秒。理想情况下,延迟应该小于 150 毫秒。我提供了示例代码,您可以自己编译并检查延迟数据
  • 任何解决方案或调整?

标签: centos ubuntu-16.04 zeromq


【解决方案1】:

建立 TCP 连接的开销并非微不足道 - 并且 ZMQ 的开销会增加,因为创建连接的动作是在幕后通过一些 TCP 来回来回完成的。

因此,first 消息的延迟不仅仅是消息本身的延迟。这是消息的延迟与建立连接所涉及的消息的延迟相结合。

要注意的另一件事是 1 个字节是一个惊人低效的有效负载,即使使用普通 TCP 也是如此。如果 ZMQ 在发送时进行任何类型的批处理,这将显着改善大量消息的延迟。我不知道它是否在幕后做任何事情,但事实仍然是 1 个字节背负着与 TCP 和 ZMQ 建立连接时相同的不可避免的开销,就像 1000 个字节一样,它只是压倒了发送 1 个字节所涉及的延迟,对于 1000 个字节可以忽略不计。

我建议您发送 2 条消息并观察每条消息的各个延迟 - 如果我是对的,第二条应该回落到 ~25µs 范围内。如果是这种情况,那么该开销是否代表问题取决于您。我怀疑它不会在实践中。

【讨论】:

  • 它不是一个 1 字节的消息。我接收任何大小的单个消息。它不是在握手期间,因为握手发生在设备连接时。在实际发送或接收消息之前,我的应用程序等待每个新连接大约 10 秒。当有一条消息从一端传递到另一端时,这种模式会在整个运行时重复
  • @NagarajuSherigar ZeroMQ 套接字不仅仅是名称奇特的 TCP 套接字。当您调用connect() 时,它们不一定会连接(在 TCP 级别上)。例如,他们可以延迟连接,直到有数据要发送。
  • @rveerd 很好,那么发送的第一条消息应该会有延迟。这里我说它存在于每条消息中。注意延迟只有在传递单个消息(不是单个字节)时才存在,当发送大量消息时,则不是延迟
  • @NagarajuSherigar 你似乎在说自相矛盾的事情。你说每条消息都有延迟,但只有一条消息,而不是很多消息。这与它只存在于第一条消息是一致的。您是否尝试过我的建议,不是发送一条或多条消息,而是发送两条消息?您确定第二条消息具有高延迟吗?
  • @NagarajuSherigar 我做了一些假设,因为你没有展示任何你展示给我们的代码是有代表性的。看来情况并非如此。所以我建议你分享你的实际代码,然后其他人可能会提出实际问题?
猜你喜欢
  • 1970-01-01
  • 2018-10-11
  • 1970-01-01
  • 2020-11-13
  • 1970-01-01
  • 2018-07-29
  • 1970-01-01
  • 2011-05-25
  • 2017-06-10
相关资源
最近更新 更多