use*_*878 5 sockets distributed distributed-computing zeromq
我正在测试majordomo经纪人的吞吐量.随github上的majordomo代码附带的test_client.c发送同步请求.我想测试majordomo代理可以实现的最大吞吐量.规范(http://rfc.zeromq.org/spec:7)表示它每秒可以切换多达一百万条消息.
首先,我更改了客户端代码以异步发送100k请求.即使在所有套接字上的HWM设置得足够高并且将TCP缓冲区增加到4 MB之后,我也会观察到三个并行运行的客户端丢包.
所以我改变了客户端一次发送10k个请求,然后为它收到的每个回复发送两个请求.我选择10k是因为这允许我并行运行多达十个客户端(每个发送100k消息)而不会丢失任何数据包.这是客户端代码:
#include "../include/mdp.h"
#include <time.h>
int main (int argc, char *argv [])
{
int verbose = (argc > 1 && streq (argv [1], "-v"));
mdp_client_t *session = mdp_client_new (argv[1], verbose);
int count1, count2;
struct timeval start,end;
gettimeofday(&start, NULL);
for (count1 = 0; count1 < 10000; count1++) {
zmsg_t *request = zmsg_new ();
zmsg_pushstr (request, "Hello world");
mdp_client_send (session, "echo", &request);
}
for (count1 = 0; count1 < 45000; count1++) {
zmsg_t *reply = mdp_client_recv (session,NULL,NULL);
if (reply)
{
zmsg_destroy (&reply);
zmsg_t *request = zmsg_new ();
zmsg_pushstr (request, "Hello world");
mdp_client_send (session, "echo", &request);
request = zmsg_new ();
zmsg_pushstr (request, "Hello world");
mdp_client_send (session, "echo", &request);
}
else
break; // Interrupted by Ctrl-C
}
/* receiving the remaining 55k replies */
for(count1 = 45000; count1 < 100000; count1++)
{
zmsg_t *reply = mdp_client_recv (session,NULL,NULL);
if (reply)
{
zmsg_destroy (&reply);
}
else
break;
}
gettimeofday(&end, NULL);
long elapsed = (end.tv_sec - start.tv_sec) +((end.tv_usec - start.tv_usec)/1000000);
printf("time = %ld\n", elapsed);
printf ("%d replies received\n", count1);
mdp_client_destroy (&session);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在同一台机器上运行了代理,工作人员和客户端.这是记录的时间:
number of clients in parallel
(each client sends 100k ) Time elapsed (seconds)
1 4
2 9
3 12
4 16
5 21
10 43
Run Code Online (Sandbox Code Playgroud)
因此,对于每100k请求,经纪人大约需要4秒钟.这是预期的行为吗?我不确定如何每秒实现百万条消息.
最近更新:
我想出了一种提高系统吞吐量的方法:
两个经纪人而不是一个.其中一个代理(broker1)负责将客户端请求发送给工作者,另一个代理(broker2)负责将工作者的响应发送给客户端.
工人向经纪人1登记.
客户端生成唯一ID并向broker2注册.
除了请求,客户端还将其唯一ID发送到broker1.
Worker从请求中提取唯一的客户端ID,并将其响应(以及必须向其发送响应的客户端ID)发送到broker2.
现在,每100k请求大约需要2秒而不是4秒(使用单个代理时).我在代理代码中添加了gettimeofday调用来测量代理本身添加了多少延迟.
这是我记录的内容
因此,大部分时间都花在代理代码中.有人可以建议如何改善这一点.
最大吞吐量受代理的最大吞吐量限制,但也受工作线程的最大吞吐量限制。
在我看来,你只开始了一名工人。如果您仔细阅读 Majordomo 协议规范,它表示代理应该能够每秒切换数百万条消息,但它并不能保证单个工作人员每秒可以处理数百万条请求。
鉴于工作人员一次仅处理一个请求,并与工作人员使用完全同步的对话(代理在收到回复之前不会发送另一个请求),因此不可能通过单个工作人员充分利用代理,或者甚至是单个工作人员:在回复和下一个请求之间执行与代理的完整网络往返,因此工作人员大部分时间都在等待。
对于初学者,您应该尝试添加更多工人:-)
编辑:快速演示。
我使用 Majordomo 模式的 Python 实现和 ZeroMQ 运行了一个 echo 服务。当然,这是 Python 代码,将进行完整的错误检查,而 C 版本应该快得多,但它显示了多个工作人员响应回复的影响。
测试设置:
结果:
使用更多客户端将在代理中产生更好的吞吐量,因为它将在多个套接字上执行 I/O,但计算总代理吞吐量并不那么容易,因此我将让您测量它。