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

結果分析

測試結果與官方差距極大,僅達到每秒萬級(已滿足需求),官方測試報告能到達每秒十萬甚至百萬級,下面是結果誤差較大的可能原因

  1. 官方測試數據 client 併發低爲 9/16/4,該測試 client 併發爲 20/100
  2. 虛擬機配置問題,2 CPU,會限制降低 client 併發性能
  3. 測試數據爲 1KB 大於 官方測試中的 0.1 KB
  4. 官方的 producer 端爲 golang 寫的客戶端,該測試直接使用 API 接口用 ab 工具發送 http 請求測試,http 連接創建銷燬費時

官方測試報告

3主機環境下,對於 100B 的消息達到了每秒百萬級

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\n", __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("====================================================\n");
    printf("MESSAGE: %d %s\n", (int)msg->body_length, msg->body);
    printf("====================================================\n");
    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\n");
        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'
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章