Majordomo经纪人吞吐量测量

时间:2014-12-15 05:48:56

标签: sockets zeromq distributed distributed-computing

我正在测试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;
}

我在同一台机器上运行代理,工作人员和客户端。这是记录的时间:

number of clients in parallel 
(each client sends 100k )                           Time elapsed (seconds)

1                                                   4                

2                                                   9

3                                                   12

4                                                   16

5                                                   21

10                                                  43

因此,对于每100k请求,经纪人大约需要4秒钟。这是预期的行为吗?我不确定如何每秒实现数百万条消息。

最新更新:

我提出了一种提高系统吞吐量的方法:

  1. 两个经纪人而不是一个经纪人。其中一个代理(broker1)负责向客户发送客户请求,另一个代理(broker2)负责将工作人员的响应发送给客户。

  2. 工人在broker1注册。

  3. 客户端生成唯一ID并向broker2注册。

  4. 除了请求,客户端还将其唯一ID发送到broker1。

  5. Worker从请求中提取唯一的客户端ID,并将其响应(以及必须向其发送响应的客户端ID)发送到broker2。

  6. 现在,每100k请求大约需要2秒而不是4秒(使用单个代理时)。我在代理代码中添加了gettimeofday调用来测量代理本身添加了多少延迟。

    这是我录制的内容

    1. 100k请求(总时间:~2秒) - &gt;经纪人增加的延迟是2秒
    2. 200k请求(总时间:~4秒) - &gt;经纪人增加的延迟是3秒
    3. 300k请求(总时间:~7秒) - &gt;经纪人增加的延迟是5秒
    4. 因此,大部分时间都花在代理代码中。有人可以建议如何改善这一点。

1 个答案:

答案 0 :(得分:0)

最大吞吐量受整个代理程序的最大吞吐量限制,但它也受到整个工作程序的最大吞吐量的限制。

在我看来,你只是开始只有一名工人。如果你仔细阅读majordomo协议规范,它说代理应该能够每秒切换到数百万条消息,但它不能保证单个工作者每秒可以处理数百万个请求。

鉴于工作者一次只处理一个请求并使用与工作者完全同步的对话(代理在收到回复之前不会发送另一个请求),所以不可能通过单个工作人员,甚至是单个工作人员:在回复和下一个请求之间执行与经纪人的完整网络往返,以便工人花费大部分时间等待。

对于初学者,你应该尝试添加更多的工人: - )

编辑:快速演示。

我使用ZeroMQ的Majordomo模式的Python实现运行了一个echo服务。当然,这是Python代码将完全错误检查,C版本应该更快,更快,但它显示了让多个工作人员响应回复的影响。

测试设置

  1. 1个客户
  2. 客户端一次最多发送1000个未完成的请求(最初发送1000个,然后每次收到响应时客户端发送一个新请求);
  3. 客户端总共发送100,000个请求;
  4. <强>结果:

    • 使用1名工作人员,客户端在13.6秒(~7300 RPS)内获得100,000个回复。
    • 使用2名工作人员,客户在8.0秒内获得100,000回复(~12500 RPS)。
    • 使用3名工作人员,客户端在7.8秒内获得100,000回复(~13000 RPS)。

    使用更多客户端将在代理中产生更好的吞吐量,因为它将在多个套接字上执行I / O,但是计算总代理吞吐量并不容易,因此我将让您测量它。