我需要构建一个实时低延迟消息传递系统。
我阅读了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毫秒。
有什么方法可以减少延迟?
答案 0 :(得分:0)
建立TCP连接的开销并不是微不足道的-ZMQ的开销增加了,因为创建连接的动作是在幕后通过一些TCP来回完成的。
因此,您的 first 消息的延迟不仅仅是消息本身的延迟。它是消息的延迟与建立连接所涉及的消息的延迟相结合。
要注意的另一件事是,即使使用香草TCP,1个字节也是惊人地无效的有效负载。如果ZMQ在发送时进行任何批处理,则将大大改善大量消息的延迟。我不知道它是否在幕后进行了任何操作,但是事实仍然是1个字节背负着相同的不可避免的开销,TCP和ZMQ都为建立1000个字节而建立连接,这只是不堪重负发送1个字节所需的延迟时间,对于1000个字节而言可以忽略不计。
我建议您发送2条消息,并注意每条消息的个别延迟-如果我是对的,则第二条消息应回落到〜25µs范围内。如果是这种情况,则取决于您的开销是否代表问题。我怀疑它不会在实践中。