From b375f5919ea7458ecf453cbe58f05a6085a954f0 Mon Sep 17 00:00:00 2001 From: Huang Zhw Date: Wed, 25 Aug 2021 19:58:35 +0800 Subject: [PATCH] redis-benchmark: make show throughput in only one thread. (#9146) In multipe threads mode, every thread output throughput info. This may cause some problems: - Bug in https://github.com/redis/redis/pull/8615; - The show throughput is called too frequently; - showThroughput which updates shared variable lacks synchronization mechanism. This commit also reverts changes in #8615 and changes time event interval to macro. --- src/redis-benchmark.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/redis-benchmark.c b/src/redis-benchmark.c index c6ecf757c..74c8be1a6 100644 --- a/src/redis-benchmark.c +++ b/src/redis-benchmark.c @@ -70,6 +70,7 @@ #define CONFIG_LATENCY_HISTOGRAM_MIN_VALUE 10L /* >= 10 usecs */ #define CONFIG_LATENCY_HISTOGRAM_MAX_VALUE 3000000L /* <= 30 secs(us precision) */ #define CONFIG_LATENCY_HISTOGRAM_INSTANT_MAX_VALUE 3000000L /* <= 3 secs(us precision) */ +#define SHOW_THROUGHPUT_INTERVAL 250 /* 250ms */ #define CLIENT_GET_EVENTLOOP(c) \ (c->thread_id >= 0 ? config.threads[c->thread_id]->el : config.el) @@ -1019,7 +1020,7 @@ static benchmarkThread *createBenchmarkThread(int index) { if (thread == NULL) return NULL; thread->index = index; thread->el = aeCreateEventLoop(1024*10); - aeCreateTimeEvent(thread->el,1,showThroughput,NULL,NULL); + aeCreateTimeEvent(thread->el,1,showThroughput,(void *)thread,NULL); return thread; } @@ -1622,7 +1623,7 @@ usage: int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData) { UNUSED(eventLoop); UNUSED(id); - UNUSED(clientData); + benchmarkThread *thread = (benchmarkThread *)clientData; int liveclients = 0; int requests_finished = 0; int previous_requests_finished = 0; @@ -1630,7 +1631,7 @@ int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData atomicGet(config.liveclients, liveclients); atomicGet(config.requests_finished, requests_finished); atomicGet(config.previous_requests_finished, previous_requests_finished); - + if (liveclients == 0 && requests_finished != config.requests) { fprintf(stderr,"All clients disconnected... aborting.\n"); exit(1); @@ -1639,11 +1640,15 @@ int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData aeStop(eventLoop); return AE_NOMORE; } - if (config.csv) return 250; + if (config.csv) return SHOW_THROUGHPUT_INTERVAL; + /* only first thread output throughput */ + if (thread != NULL && thread->index != 0) { + return SHOW_THROUGHPUT_INTERVAL; + } if (config.idlemode == 1) { printf("clients: %d\r", config.liveclients); fflush(stdout); - return 250; + return SHOW_THROUGHPUT_INTERVAL; } const float dt = (float)(current_tick-config.start)/1000.0; const float rps = (float)requests_finished/dt; @@ -1653,12 +1658,10 @@ int showThroughput(struct aeEventLoop *eventLoop, long long id, void *clientData atomicSet(config.previous_requests_finished,requests_finished); printf("%*s\r", config.last_printed_bytes, " "); /* ensure there is a clean line */ int printed_bytes = printf("%s: rps=%.1f (overall: %.1f) avg_msec=%.3f (overall: %.3f)\r", config.title, instantaneous_rps, rps, hdr_mean(config.current_sec_latency_histogram)/1000.0f, hdr_mean(config.latency_histogram)/1000.0f); - if (printed_bytes > config.last_printed_bytes){ - config.last_printed_bytes = printed_bytes; - } + config.last_printed_bytes = printed_bytes; hdr_reset(config.current_sec_latency_histogram); fflush(stdout); - return 250; /* every 250ms */ + return SHOW_THROUGHPUT_INTERVAL; } /* Return true if the named test was selected using the -t command line