单个消息的最差延迟

时间:2019-07-12 05:26:21

标签: centos ubuntu-16.04 zeromq

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

我阅读了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示例,它向我显示了相同的延迟数字

sender.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毫秒。

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

1 个答案:

答案 0 :(得分:0)

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

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

要注意的另一件事是,即使使用香草TCP,1个字节也是惊人地无效的有效负载。如果ZMQ在发送时进行任何批处理,则将大大改善大量消息的延迟。我不知道它是否在幕后进行了任何操作,但是事实仍然是1个字节背负着相同的不可避免的开销,TCP和ZMQ都为建立1000个字节而建立连接,这只是不堪重负发送1个字节所需的延迟时间,对于1000个字节而言可以忽略不计。

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