NSQ単機試験(単一topic)


nsq環境構築


公式ドキュメント公式ドキュメント中国語版公式ドキュメント中国語版PDF

nsq仮想マシンテスト(単一topic)


テスト環境


object
describe
cpu
2
memory
8G
nsqd count
1
nsqlookup
1
message size
1KB
message count
100000
topic count
1
channel count
20/100
client count
20/100

テストレポート


channel count
write mb/s
write kops/s
read mb/s
read kops/s
per_channel_read ops/s
20
19.9
15.2
8.0
8.0
400
100
7.73
5.9
33.3
33.3
333

結果分析


テスト結果と公式の差は極めて大きく、毎秒万級(需要を満たしている)に達し、公式テスト報告書は毎秒10万級から百万級に達することができ、以下は結果の誤差が大きい可能性がある.
  • 公式テストデータclientの同時低さは9/16/4であり、このテストclientの同時低さは20/100
  • である.
  • 仮想マシンの構成の問題、2 CPU、client同時性能の低下を制限する
  • 試験データは1 KBが公式試験中の0.1 KB
  • より大きい
  • の公式producer側はgolangが書いたクライアントであり、このテストはAPIインタフェースを直接使用してabツールでhttpリクエストテストを送信し、http接続が破棄時間
  • を作成する.

    公式テストレポート


    3ホスト環境において、100 Bに対するメッセージは毎秒百万レベルに達した

    3ホストおよび4ホストのテスト


    テスト環境
    object
    describe
    nsqlookup
    1
    message size
    0.1 KB
    topic count
    3
    channel count
    3
    テストレポート
    nsqd(host)
    producer count
    consumer count
    write mb/s
    write kops/s
    read mb/s
    read kops/s
    3
    9
    9
    80.315
    842
    76.946
    807
    4
    16
    16
    105.898
    1110
    100.956
    1059

    スタンドアロンテスト


    producer
    consumer
    write mb/s
    write kops/s
    read mb/s
    read kops/s
    1
    4
    31.738
    166
    82.500
    433
    4
    4
    36.321
    190
    135.130
    708

    スクリプト関連のテスト


    nsqd/nsqlookupd/nsqadminの起動

    #!/bin/bash
    readonly memQueueSize="${MEM_QUEUE_SIZE:-1000000}"
    set -e
    set -u
    
    echo "# using --mem-queue-size=$memQueueSize"
    
    if [ ! -x ./nsqd ]
    then
      echo "Please copy executable nsqd here"
      exit
    fi
    if [ ! -x ./nsqlookupd ]
    then
      echo "Please copy executable nsqlookupd here"
      exit
    fi
    
    echo "# running nsqlookupd and nsqd"
    rm -f *.dat
    ./nsqlookupd --broadcast-address=127.0.0.1 >/dev/null 2>&1 &
    nsqlookupd_pid=$!
    
    ./nsqd --mem-queue-size=$memQueueSize --lookupd-tcp-address=127.0.0.1:4160 --broadcast-address=127.0.0.1 >/dev/null 2>&1 &
    nsqd_pid=$!
    
    ./nsqadmin --lookupd-http-address=127.0.0.1:4161 >/dev/null 2>&1 &
    nsqadmin_pid=$!
    

    topic/channelの作成

    #!/bin/bash
    readonly channelCount="${1:-1}"
    
    echo "# using --channel-count=${channelCount}"
    
    echo "# creating topic/channel"
    for i in $(seq 1 ${channelCount})
    do
        curl --silent -X POST "http://127.0.0.1:4151/topic/create?topic=topic_1" >/dev/null 2>&1
        if [ $i -lt 10 ]
        then
            curl --silent -X POST "http://127.0.0.1:4151/channel/create?topic=topic_1&channel=channel_0${i}" >/dev/null 2>&1
        else
            curl --silent -X POST "http://127.0.0.1:4151/channel/create?topic=topic_1&channel=channel_${i}" >/dev/null 2>&1
        fi
    done
    

    クライアントコードのテスト

    #include "nsq.h"
    
    static void message_handler(nsqRdr *rdr, nsqdConn *conn, nsqMsg *msg, void *ctx)
    {
        //_DEBUG("%s: %lld, %d, %s, %lu, %.*s
    ", __FUNCTION__, msg->timestamp, msg->attempts, msg->id, // msg->body_length, (int)msg->body_length, msg->body); int ret = 0; //TestNsqMsgContext * test_ctx = (TestNsqMsgContext *)ctx; //int ret= ctx->process(msg->body, msg->body_length); printf("====================================================
    "); printf("MESSAGE: %d %s
    ", (int)msg->body_length, msg->body); printf("====================================================
    "); buffer_reset(conn->command_buf); if(ret < 0){ nsq_requeue(conn->command_buf, msg->id, 100); }else{ nsq_finish(conn->command_buf, msg->id); } buffered_socket_write_buffer(conn->bs, conn->command_buf); buffer_reset(conn->command_buf); nsq_ready(conn->command_buf, rdr->max_in_flight); buffered_socket_write_buffer(conn->bs, conn->command_buf); free_nsq_message(msg); } int main(int argc, char **argv) { if (argc < 4) { printf("not enough args from command line
    "); return 1; } nsqRdr *rdr; struct ev_loop *loop; void *ctx = NULL; //(void *)(new TestNsqMsgContext()); loop = ev_default_loop(0); rdr = new_nsq_reader(loop, argv[2], argv[3], ctx, NULL, NULL, NULL, message_handler); #ifdef NSQD_STANDALONE nsq_reader_connect_to_nsqd(rdr, argv[1], 4150); // nsq_reader_connect_to_nsqd(rdr, "127.0.0.1", 14150); #else nsq_reader_add_nsqlookupd_endpoint(rdr, argv[1], 4161); #endif nsq_run(loop); return 0; }

    テストクライアントの起動

    #!/bin/bash
    readonly channelCount="${1:-1}"
    
    echo "# using --channel-count=$channelCount"
    
    if [ ! -x ./test-nsqd ]
    then
      echo "Please copy executable test_nsqd here"
      exit
    fi
    
    echo "# running test_nsqd"
    for i in $(seq 1 ${channelCount})
    do
        if [ $i -lt 10 ]
        then
            ./test-nsqd 127.0.0.1 topic_1 channel_0${i} >/dev/null 2>&1 &
        else
            ./test-nsqd 127.0.0.1 topic_1 channel_${i} >/dev/null 2>&1 &
        fi
    done
    

    ab圧力試験

    ab -c 10 -n 100000 -p 1.txt -T '/text/plain' 'http://127.0.0.1:4151/pub?topic=topic_1'