Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 666 lines (603 sloc) 21.924 kb
ed9b544 Salvatore Sanfilippo first commit
authored
1 /* Redis benchmark utility.
2 *
12d090d Salvatore Sanfilippo A problem with replication with multiple slaves connectiong to a single ...
authored
3 * Copyright (c) 2009-2010, Salvatore Sanfilippo <antirez at gmail dot com>
ed9b544 Salvatore Sanfilippo first commit
authored
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of Redis nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without
16 * specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
5f5b984 Salvatore Sanfilippo Partial qsort implemented in SORT command, only when both BY and LIMIT i...
authored
31 #include "fmacros.h"
32
ed9b544 Salvatore Sanfilippo first commit
authored
33 #include <stdio.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <unistd.h>
37 #include <errno.h>
38 #include <sys/time.h>
39 #include <signal.h>
40 #include <assert.h>
41
42 #include "ae.h"
43 #include "anet.h"
44 #include "sds.h"
45 #include "adlist.h"
46 #include "zmalloc.h"
47
48 #define REPLY_INT 0
49 #define REPLY_RETCODE 1
50 #define REPLY_BULK 2
6c4e61b Salvatore Sanfilippo redis-benchmark multi bulk reply support hopefully fixed
authored
51 #define REPLY_MBULK 3
ed9b544 Salvatore Sanfilippo first commit
authored
52
53 #define CLIENT_CONNECTING 0
54 #define CLIENT_SENDQUERY 1
55 #define CLIENT_READREPLY 2
56
57 #define MAX_LATENCY 5000
58
59 #define REDIS_NOTUSED(V) ((void) V)
60
61 static struct config {
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
62 int debug;
ed9b544 Salvatore Sanfilippo first commit
authored
63 int numclients;
64 int requests;
65 int liveclients;
66 int donerequests;
67 int keysize;
68 int datasize;
57172ff Salvatore Sanfilippo CPP client added thanks to Brian Hammond
authored
69 int randomkeys;
ecfaf6d Salvatore Sanfilippo benchmark utility now supports random keys
authored
70 int randomkeys_keyspacelen;
ed9b544 Salvatore Sanfilippo first commit
authored
71 aeEventLoop *el;
72 char *hostip;
73 int hostport;
74 int keepalive;
75 long long start;
76 long long totlatency;
77 int *latency;
78 list *clients;
79 int quiet;
80 int loop;
266373b Salvatore Sanfilippo ae.c now supports multiple polling API modules, even if only ae_select.c...
authored
81 int idlemode;
ed9b544 Salvatore Sanfilippo first commit
authored
82 } config;
83
84 typedef struct _client {
85 int state;
86 int fd;
87 sds obuf;
88 sds ibuf;
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
89 int mbulk; /* Number of elements in an mbulk reply */
ed9b544 Salvatore Sanfilippo first commit
authored
90 int readlen; /* readlen == -1 means read a single line */
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
91 int totreceived;
ed9b544 Salvatore Sanfilippo first commit
authored
92 unsigned int written; /* bytes of 'obuf' already written */
93 int replytype;
94 long long start; /* start time in milliseconds */
95 } *client;
96
97 /* Prototypes */
98 static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask);
99 static void createMissingClients(client c);
100
101 /* Implementation */
102 static long long mstime(void) {
103 struct timeval tv;
104 long long mst;
105
106 gettimeofday(&tv, NULL);
107 mst = ((long)tv.tv_sec)*1000;
108 mst += tv.tv_usec/1000;
109 return mst;
110 }
111
112 static void freeClient(client c) {
113 listNode *ln;
114
115 aeDeleteFileEvent(config.el,c->fd,AE_WRITABLE);
116 aeDeleteFileEvent(config.el,c->fd,AE_READABLE);
117 sdsfree(c->ibuf);
118 sdsfree(c->obuf);
119 close(c->fd);
120 zfree(c);
121 config.liveclients--;
122 ln = listSearchKey(config.clients,c);
123 assert(ln != NULL);
124 listDelNode(config.clients,ln);
125 }
126
127 static void freeAllClients(void) {
128 listNode *ln = config.clients->head, *next;
129
130 while(ln) {
131 next = ln->next;
132 freeClient(ln->value);
133 ln = next;
134 }
135 }
136
137 static void resetClient(client c) {
138 aeDeleteFileEvent(config.el,c->fd,AE_WRITABLE);
139 aeDeleteFileEvent(config.el,c->fd,AE_READABLE);
266373b Salvatore Sanfilippo ae.c now supports multiple polling API modules, even if only ae_select.c...
authored
140 aeCreateFileEvent(config.el,c->fd, AE_WRITABLE,writeHandler,c);
ed9b544 Salvatore Sanfilippo first commit
authored
141 sdsfree(c->ibuf);
142 c->ibuf = sdsempty();
89ee361 Salvatore Sanfilippo benchmark.c fixes
authored
143 c->readlen = (c->replytype == REPLY_BULK ||
144 c->replytype == REPLY_MBULK) ? -1 : 0;
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
145 c->mbulk = -1;
ed9b544 Salvatore Sanfilippo first commit
authored
146 c->written = 0;
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
147 c->totreceived = 0;
ed9b544 Salvatore Sanfilippo first commit
authored
148 c->state = CLIENT_SENDQUERY;
149 c->start = mstime();
7407797 Salvatore Sanfilippo Python client updated pushing from Ludo's repository
authored
150 createMissingClients(c);
ed9b544 Salvatore Sanfilippo first commit
authored
151 }
152
ecfaf6d Salvatore Sanfilippo benchmark utility now supports random keys
authored
153 static void randomizeClientKey(client c) {
154 char *p;
155 char buf[32];
156 long r;
157
158 p = strstr(c->obuf, "_rand");
159 if (!p) return;
160 p += 5;
161 r = random() % config.randomkeys_keyspacelen;
162 sprintf(buf,"%ld",r);
163 memcpy(p,buf,strlen(buf));
164 }
165
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
166 static void prepareClientForReply(client c, int type) {
167 if (type == REPLY_BULK) {
168 c->replytype = REPLY_BULK;
169 c->readlen = -1;
170 } else if (type == REPLY_MBULK) {
171 c->replytype = REPLY_MBULK;
172 c->readlen = -1;
173 c->mbulk = -1;
174 } else {
175 c->replytype = type;
176 c->readlen = 0;
177 }
178 }
179
ed9b544 Salvatore Sanfilippo first commit
authored
180 static void clientDone(client c) {
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
181 static int last_tot_received = 1;
182
ed9b544 Salvatore Sanfilippo first commit
authored
183 long long latency;
184 config.donerequests ++;
185 latency = mstime() - c->start;
186 if (latency > MAX_LATENCY) latency = MAX_LATENCY;
187 config.latency[latency]++;
188
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
189 if (config.debug && last_tot_received != c->totreceived) {
190 printf("Tot bytes received: %d\n", c->totreceived);
191 last_tot_received = c->totreceived;
192 }
ed9b544 Salvatore Sanfilippo first commit
authored
193 if (config.donerequests == config.requests) {
194 freeClient(c);
195 aeStop(config.el);
196 return;
197 }
198 if (config.keepalive) {
199 resetClient(c);
ecfaf6d Salvatore Sanfilippo benchmark utility now supports random keys
authored
200 if (config.randomkeys) randomizeClientKey(c);
ed9b544 Salvatore Sanfilippo first commit
authored
201 } else {
202 config.liveclients--;
203 createMissingClients(c);
204 config.liveclients++;
205 freeClient(c);
206 }
207 }
208
209 static void readHandler(aeEventLoop *el, int fd, void *privdata, int mask)
210 {
211 char buf[1024];
212 int nread;
213 client c = privdata;
214 REDIS_NOTUSED(el);
215 REDIS_NOTUSED(fd);
216 REDIS_NOTUSED(mask);
217
218 nread = read(c->fd, buf, 1024);
219 if (nread == -1) {
220 fprintf(stderr, "Reading from socket: %s\n", strerror(errno));
221 freeClient(c);
222 return;
223 }
224 if (nread == 0) {
225 fprintf(stderr, "EOF from client\n");
226 freeClient(c);
227 return;
228 }
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
229 c->totreceived += nread;
ed9b544 Salvatore Sanfilippo first commit
authored
230 c->ibuf = sdscatlen(c->ibuf,buf,nread);
231
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
232 processdata:
6c4e61b Salvatore Sanfilippo redis-benchmark multi bulk reply support hopefully fixed
authored
233 /* Are we waiting for the first line of the command of for sdf
234 * count in bulk or multi bulk operations? */
ed9b544 Salvatore Sanfilippo first commit
authored
235 if (c->replytype == REPLY_INT ||
236 c->replytype == REPLY_RETCODE ||
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
237 (c->replytype == REPLY_BULK && c->readlen == -1) ||
238 (c->replytype == REPLY_MBULK && c->readlen == -1) ||
239 (c->replytype == REPLY_MBULK && c->mbulk == -1)) {
ed9b544 Salvatore Sanfilippo first commit
authored
240 char *p;
241
6c4e61b Salvatore Sanfilippo redis-benchmark multi bulk reply support hopefully fixed
authored
242 /* Check if the first line is complete. This is only true if
243 * there is a newline inside the buffer. */
ed9b544 Salvatore Sanfilippo first commit
authored
244 if ((p = strchr(c->ibuf,'\n')) != NULL) {
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
245 if (c->replytype == REPLY_BULK ||
246 (c->replytype == REPLY_MBULK && c->mbulk != -1))
247 {
6c4e61b Salvatore Sanfilippo redis-benchmark multi bulk reply support hopefully fixed
authored
248 /* Read the count of a bulk reply (being it a single bulk or
249 * a multi bulk reply). "$<count>" for the protocol spec. */
ed9b544 Salvatore Sanfilippo first commit
authored
250 *p = '\0';
251 *(p-1) = '\0';
4c26a79 Salvatore Sanfilippo redis-benchmark sync with the new protocol
authored
252 c->readlen = atoi(c->ibuf+1)+2;
89ee361 Salvatore Sanfilippo benchmark.c fixes
authored
253 // printf("BULK ATOI: %s\n", c->ibuf+1);
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
254 /* Handle null bulk reply "$-1" */
ecfaf6d Salvatore Sanfilippo benchmark utility now supports random keys
authored
255 if (c->readlen-2 == -1) {
ed9b544 Salvatore Sanfilippo first commit
authored
256 clientDone(c);
257 return;
258 }
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
259 /* Leave all the rest in the input buffer */
260 c->ibuf = sdsrange(c->ibuf,(p-c->ibuf)+1,-1);
6c4e61b Salvatore Sanfilippo redis-benchmark multi bulk reply support hopefully fixed
authored
261 /* fall through to reach the point where the code will try
262 * to check if the bulk reply is complete. */
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
263 } else if (c->replytype == REPLY_MBULK && c->mbulk == -1) {
6c4e61b Salvatore Sanfilippo redis-benchmark multi bulk reply support hopefully fixed
authored
264 /* Read the count of a multi bulk reply. That is, how many
265 * bulk replies we have to read next. "*<count>" protocol. */
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
266 *p = '\0';
267 *(p-1) = '\0';
268 c->mbulk = atoi(c->ibuf+1);
269 /* Handle null bulk reply "*-1" */
270 if (c->mbulk == -1) {
271 clientDone(c);
272 return;
273 }
89ee361 Salvatore Sanfilippo benchmark.c fixes
authored
274 // printf("%p) %d elements list\n", c, c->mbulk);
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
275 /* Leave all the rest in the input buffer */
ed9b544 Salvatore Sanfilippo first commit
authored
276 c->ibuf = sdsrange(c->ibuf,(p-c->ibuf)+1,-1);
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
277 goto processdata;
ed9b544 Salvatore Sanfilippo first commit
authored
278 } else {
279 c->ibuf = sdstrim(c->ibuf,"\r\n");
280 clientDone(c);
281 return;
282 }
283 }
284 }
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
285 /* bulk read, did we read everything? */
6c4e61b Salvatore Sanfilippo redis-benchmark multi bulk reply support hopefully fixed
authored
286 if (((c->replytype == REPLY_MBULK && c->mbulk != -1) ||
287 (c->replytype == REPLY_BULK)) && c->readlen != -1 &&
288 (unsigned)c->readlen <= sdslen(c->ibuf))
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
289 {
89ee361 Salvatore Sanfilippo benchmark.c fixes
authored
290 // printf("BULKSTATUS mbulk:%d readlen:%d sdslen:%d\n",
291 // c->mbulk,c->readlen,sdslen(c->ibuf));
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
292 if (c->replytype == REPLY_BULK) {
293 clientDone(c);
294 } else if (c->replytype == REPLY_MBULK) {
89ee361 Salvatore Sanfilippo benchmark.c fixes
authored
295 // printf("%p) %d (%d)) ",c, c->mbulk, c->readlen);
296 // fwrite(c->ibuf,c->readlen,1,stdout);
297 // printf("\n");
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
298 if (--c->mbulk == 0) {
299 clientDone(c);
300 } else {
301 c->ibuf = sdsrange(c->ibuf,c->readlen,-1);
302 c->readlen = -1;
303 goto processdata;
304 }
305 }
306 }
ed9b544 Salvatore Sanfilippo first commit
authored
307 }
308
309 static void writeHandler(aeEventLoop *el, int fd, void *privdata, int mask)
310 {
311 client c = privdata;
312 REDIS_NOTUSED(el);
313 REDIS_NOTUSED(fd);
314 REDIS_NOTUSED(mask);
315
316 if (c->state == CLIENT_CONNECTING) {
317 c->state = CLIENT_SENDQUERY;
318 c->start = mstime();
319 }
320 if (sdslen(c->obuf) > c->written) {
321 void *ptr = c->obuf+c->written;
322 int len = sdslen(c->obuf) - c->written;
323 int nwritten = write(c->fd, ptr, len);
324 if (nwritten == -1) {
61c47ec Salvatore Sanfilippo better handling of non blocking connect on redis-benchmark: EPIPE on rea...
authored
325 if (errno != EPIPE)
326 fprintf(stderr, "Writing to socket: %s\n", strerror(errno));
ed9b544 Salvatore Sanfilippo first commit
authored
327 freeClient(c);
328 return;
329 }
330 c->written += nwritten;
331 if (sdslen(c->obuf) == c->written) {
332 aeDeleteFileEvent(config.el,c->fd,AE_WRITABLE);
266373b Salvatore Sanfilippo ae.c now supports multiple polling API modules, even if only ae_select.c...
authored
333 aeCreateFileEvent(config.el,c->fd,AE_READABLE,readHandler,c);
ed9b544 Salvatore Sanfilippo first commit
authored
334 c->state = CLIENT_READREPLY;
335 }
336 }
337 }
338
339 static client createClient(void) {
340 client c = zmalloc(sizeof(struct _client));
341 char err[ANET_ERR_LEN];
342
343 c->fd = anetTcpNonBlockConnect(err,config.hostip,config.hostport);
344 if (c->fd == ANET_ERR) {
345 zfree(c);
346 fprintf(stderr,"Connect: %s\n",err);
347 return NULL;
348 }
349 anetTcpNoDelay(NULL,c->fd);
350 c->obuf = sdsempty();
351 c->ibuf = sdsempty();
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
352 c->mbulk = -1;
ed9b544 Salvatore Sanfilippo first commit
authored
353 c->readlen = 0;
354 c->written = 0;
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
355 c->totreceived = 0;
ed9b544 Salvatore Sanfilippo first commit
authored
356 c->state = CLIENT_CONNECTING;
266373b Salvatore Sanfilippo ae.c now supports multiple polling API modules, even if only ae_select.c...
authored
357 aeCreateFileEvent(config.el, c->fd, AE_WRITABLE, writeHandler, c);
ed9b544 Salvatore Sanfilippo first commit
authored
358 config.liveclients++;
359 listAddNodeTail(config.clients,c);
360 return c;
361 }
362
363 static void createMissingClients(client c) {
364 while(config.liveclients < config.numclients) {
365 client new = createClient();
366 if (!new) continue;
367 sdsfree(new->obuf);
368 new->obuf = sdsdup(c->obuf);
ecfaf6d Salvatore Sanfilippo benchmark utility now supports random keys
authored
369 if (config.randomkeys) randomizeClientKey(c);
b892cab Salvatore Sanfilippo redis-benchmark hopefully last bug with multi bulk reply fixed
authored
370 prepareClientForReply(new,c->replytype);
ed9b544 Salvatore Sanfilippo first commit
authored
371 }
372 }
373
374 static void showLatencyReport(char *title) {
375 int j, seen = 0;
376 float perc, reqpersec;
377
378 reqpersec = (float)config.donerequests/((float)config.totlatency/1000);
379 if (!config.quiet) {
380 printf("====== %s ======\n", title);
381 printf(" %d requests completed in %.2f seconds\n", config.donerequests,
382 (float)config.totlatency/1000);
383 printf(" %d parallel clients\n", config.numclients);
384 printf(" %d bytes payload\n", config.datasize);
385 printf(" keep alive: %d\n", config.keepalive);
386 printf("\n");
387 for (j = 0; j <= MAX_LATENCY; j++) {
388 if (config.latency[j]) {
389 seen += config.latency[j];
390 perc = ((float)seen*100)/config.donerequests;
391 printf("%.2f%% <= %d milliseconds\n", perc, j);
392 }
393 }
394 printf("%.2f requests per second\n\n", reqpersec);
395 } else {
396 printf("%s: %.2f requests per second\n", title, reqpersec);
397 }
398 }
399
400 static void prepareForBenchmark(void)
401 {
402 memset(config.latency,0,sizeof(int)*(MAX_LATENCY+1));
403 config.start = mstime();
404 config.donerequests = 0;
405 }
406
407 static void endBenchmark(char *title) {
408 config.totlatency = mstime()-config.start;
409 showLatencyReport(title);
410 freeAllClients();
411 }
412
413 void parseOptions(int argc, char **argv) {
414 int i;
415
416 for (i = 1; i < argc; i++) {
417 int lastarg = i==argc-1;
418
419 if (!strcmp(argv[i],"-c") && !lastarg) {
420 config.numclients = atoi(argv[i+1]);
421 i++;
422 } else if (!strcmp(argv[i],"-n") && !lastarg) {
423 config.requests = atoi(argv[i+1]);
424 i++;
425 } else if (!strcmp(argv[i],"-k") && !lastarg) {
426 config.keepalive = atoi(argv[i+1]);
427 i++;
428 } else if (!strcmp(argv[i],"-h") && !lastarg) {
429 char *ip = zmalloc(32);
430 if (anetResolve(NULL,argv[i+1],ip) == ANET_ERR) {
431 printf("Can't resolve %s\n", argv[i]);
432 exit(1);
433 }
434 config.hostip = ip;
435 i++;
436 } else if (!strcmp(argv[i],"-p") && !lastarg) {
437 config.hostport = atoi(argv[i+1]);
438 i++;
439 } else if (!strcmp(argv[i],"-d") && !lastarg) {
440 config.datasize = atoi(argv[i+1]);
441 i++;
442 if (config.datasize < 1) config.datasize=1;
443 if (config.datasize > 1024*1024) config.datasize = 1024*1024;
ecfaf6d Salvatore Sanfilippo benchmark utility now supports random keys
authored
444 } else if (!strcmp(argv[i],"-r") && !lastarg) {
57172ff Salvatore Sanfilippo CPP client added thanks to Brian Hammond
authored
445 config.randomkeys = 1;
ecfaf6d Salvatore Sanfilippo benchmark utility now supports random keys
authored
446 config.randomkeys_keyspacelen = atoi(argv[i+1]);
447 if (config.randomkeys_keyspacelen < 0)
448 config.randomkeys_keyspacelen = 0;
449 i++;
ed9b544 Salvatore Sanfilippo first commit
authored
450 } else if (!strcmp(argv[i],"-q")) {
451 config.quiet = 1;
452 } else if (!strcmp(argv[i],"-l")) {
453 config.loop = 1;
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
454 } else if (!strcmp(argv[i],"-D")) {
455 config.debug = 1;
266373b Salvatore Sanfilippo ae.c now supports multiple polling API modules, even if only ae_select.c...
authored
456 } else if (!strcmp(argv[i],"-I")) {
457 config.idlemode = 1;
ed9b544 Salvatore Sanfilippo first commit
authored
458 } else {
459 printf("Wrong option '%s' or option argument missing\n\n",argv[i]);
460 printf("Usage: redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>]\n\n");
461 printf(" -h <hostname> Server hostname (default 127.0.0.1)\n");
462 printf(" -p <hostname> Server port (default 6379)\n");
463 printf(" -c <clients> Number of parallel connections (default 50)\n");
464 printf(" -n <requests> Total number of requests (default 10000)\n");
465 printf(" -d <size> Data size of SET/GET value in bytes (default 2)\n");
466 printf(" -k <boolean> 1=keep alive 0=reconnect (default 1)\n");
b1ad58e Salvatore Sanfilippo redis-benchmark now implements Set commands benchmarks
authored
467 printf(" -r <keyspacelen> Use random keys for SET/GET/INCR, random values for SADD\n");
ecfaf6d Salvatore Sanfilippo benchmark utility now supports random keys
authored
468 printf(" Using this option the benchmark will get/set keys\n");
469 printf(" in the form mykey_rand000000012456 instead of constant\n");
470 printf(" keys, the <keyspacelen> argument determines the max\n");
471 printf(" number of values for the random number. For instance\n");
472 printf(" if set to 10 only rand000000000000 - rand000000000009\n");
473 printf(" range will be allowed.\n");
ed9b544 Salvatore Sanfilippo first commit
authored
474 printf(" -q Quiet. Just show query/sec values\n");
475 printf(" -l Loop. Run the tests forever\n");
266373b Salvatore Sanfilippo ae.c now supports multiple polling API modules, even if only ae_select.c...
authored
476 printf(" -I Idle mode. Just open N idle connections and wait.\n");
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
477 printf(" -D Debug mode. more verbose.\n");
ed9b544 Salvatore Sanfilippo first commit
authored
478 exit(1);
479 }
480 }
481 }
482
483 int main(int argc, char **argv) {
484 client c;
485
486 signal(SIGHUP, SIG_IGN);
487 signal(SIGPIPE, SIG_IGN);
488
58cd710 Salvatore Sanfilippo debug mode in redis-bench
authored
489 config.debug = 0;
ed9b544 Salvatore Sanfilippo first commit
authored
490 config.numclients = 50;
491 config.requests = 10000;
492 config.liveclients = 0;
493 config.el = aeCreateEventLoop();
494 config.keepalive = 1;
495 config.donerequests = 0;
496 config.datasize = 3;
57172ff Salvatore Sanfilippo CPP client added thanks to Brian Hammond
authored
497 config.randomkeys = 0;
ecfaf6d Salvatore Sanfilippo benchmark utility now supports random keys
authored
498 config.randomkeys_keyspacelen = 0;
ed9b544 Salvatore Sanfilippo first commit
authored
499 config.quiet = 0;
500 config.loop = 0;
266373b Salvatore Sanfilippo ae.c now supports multiple polling API modules, even if only ae_select.c...
authored
501 config.idlemode = 0;
ed9b544 Salvatore Sanfilippo first commit
authored
502 config.latency = NULL;
503 config.clients = listCreate();
504 config.latency = zmalloc(sizeof(int)*(MAX_LATENCY+1));
505
506 config.hostip = "127.0.0.1";
507 config.hostport = 6379;
508
509 parseOptions(argc,argv);
510
511 if (config.keepalive == 0) {
c325149 Salvatore Sanfilippo benchmark now outputs the right command line to shorten the TIME_WAIT in...
authored
512 printf("WARNING: keepalive disabled, you probably need 'echo 1 > /proc/sys/net/ipv4/tcp_tw_reuse' for Linux and 'sudo sysctl -w net.inet.tcp.msl=1000' for Mac OS X in order to use a lot of clients/requests\n");
ed9b544 Salvatore Sanfilippo first commit
authored
513 }
514
266373b Salvatore Sanfilippo ae.c now supports multiple polling API modules, even if only ae_select.c...
authored
515 if (config.idlemode) {
516 printf("Creating %d idle connections and waiting forever (Ctrl+C when done)\n", config.numclients);
517 prepareForBenchmark();
518 c = createClient();
519 if (!c) exit(1);
520 c->obuf = sdsempty();
521 prepareClientForReply(c,REPLY_RETCODE); /* will never receive it */
522 createMissingClients(c);
523 aeMain(config.el);
524 /* and will wait for every */
525 }
526
ed9b544 Salvatore Sanfilippo first commit
authored
527 do {
528 prepareForBenchmark();
529 c = createClient();
530 if (!c) exit(1);
6766f45 Salvatore Sanfilippo multi bulk requests in redis-benchmark, default fsync policy changed to ...
authored
531 c->obuf = sdscat(c->obuf,"PING\r\n");
532 prepareClientForReply(c,REPLY_RETCODE);
533 createMissingClients(c);
534 aeMain(config.el);
535 endBenchmark("PING");
536
537 prepareForBenchmark();
538 c = createClient();
539 if (!c) exit(1);
540 c->obuf = sdscat(c->obuf,"*1\r\n$4\r\nPING\r\n");
541 prepareClientForReply(c,REPLY_RETCODE);
542 createMissingClients(c);
543 aeMain(config.el);
544 endBenchmark("PING (multi bulk)");
545
546 prepareForBenchmark();
547 c = createClient();
548 if (!c) exit(1);
57172ff Salvatore Sanfilippo CPP client added thanks to Brian Hammond
authored
549 c->obuf = sdscatprintf(c->obuf,"SET foo_rand000000000000 %d\r\n",config.datasize);
ed9b544 Salvatore Sanfilippo first commit
authored
550 {
551 char *data = zmalloc(config.datasize+2);
552 memset(data,'x',config.datasize);
553 data[config.datasize] = '\r';
554 data[config.datasize+1] = '\n';
555 c->obuf = sdscatlen(c->obuf,data,config.datasize+2);
556 }
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
557 prepareClientForReply(c,REPLY_RETCODE);
ed9b544 Salvatore Sanfilippo first commit
authored
558 createMissingClients(c);
559 aeMain(config.el);
560 endBenchmark("SET");
561
562 prepareForBenchmark();
563 c = createClient();
564 if (!c) exit(1);
57172ff Salvatore Sanfilippo CPP client added thanks to Brian Hammond
authored
565 c->obuf = sdscat(c->obuf,"GET foo_rand000000000000\r\n");
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
566 prepareClientForReply(c,REPLY_BULK);
ed9b544 Salvatore Sanfilippo first commit
authored
567 createMissingClients(c);
568 aeMain(config.el);
569 endBenchmark("GET");
570
571 prepareForBenchmark();
572 c = createClient();
573 if (!c) exit(1);
57172ff Salvatore Sanfilippo CPP client added thanks to Brian Hammond
authored
574 c->obuf = sdscat(c->obuf,"INCR counter_rand000000000000\r\n");
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
575 prepareClientForReply(c,REPLY_INT);
ed9b544 Salvatore Sanfilippo first commit
authored
576 createMissingClients(c);
577 aeMain(config.el);
578 endBenchmark("INCR");
579
580 prepareForBenchmark();
581 c = createClient();
582 if (!c) exit(1);
583 c->obuf = sdscat(c->obuf,"LPUSH mylist 3\r\nbar\r\n");
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
584 prepareClientForReply(c,REPLY_INT);
ed9b544 Salvatore Sanfilippo first commit
authored
585 createMissingClients(c);
586 aeMain(config.el);
587 endBenchmark("LPUSH");
588
589 prepareForBenchmark();
590 c = createClient();
591 if (!c) exit(1);
592 c->obuf = sdscat(c->obuf,"LPOP mylist\r\n");
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
593 prepareClientForReply(c,REPLY_BULK);
ed9b544 Salvatore Sanfilippo first commit
authored
594 createMissingClients(c);
595 aeMain(config.el);
596 endBenchmark("LPOP");
597
9f3c422 Salvatore Sanfilippo Kill the background saving process before performing SHUTDOWN to avoid r...
authored
598 prepareForBenchmark();
599 c = createClient();
600 if (!c) exit(1);
b1ad58e Salvatore Sanfilippo redis-benchmark now implements Set commands benchmarks
authored
601 c->obuf = sdscat(c->obuf,"SADD myset 24\r\ncounter_rand000000000000\r\n");
602 prepareClientForReply(c,REPLY_RETCODE);
603 createMissingClients(c);
604 aeMain(config.el);
605 endBenchmark("SADD");
606
607 prepareForBenchmark();
608 c = createClient();
609 if (!c) exit(1);
610 c->obuf = sdscat(c->obuf,"SPOP myset\r\n");
611 prepareClientForReply(c,REPLY_BULK);
612 createMissingClients(c);
613 aeMain(config.el);
614 endBenchmark("SPOP");
615
616 prepareForBenchmark();
617 c = createClient();
618 if (!c) exit(1);
2fd3095 Salvatore Sanfilippo multi-bulk reply support for redis-bench, and as a result LRANGE is not ...
authored
619 c->obuf = sdscat(c->obuf,"LPUSH mylist 3\r\nbar\r\n");
620 prepareClientForReply(c,REPLY_RETCODE);
621 createMissingClients(c);
622 aeMain(config.el);
623 endBenchmark("LPUSH (again, in order to bench LRANGE)");
624
625 prepareForBenchmark();
626 c = createClient();
627 if (!c) exit(1);
628 c->obuf = sdscat(c->obuf,"LRANGE mylist 0 99\r\n");
629 prepareClientForReply(c,REPLY_MBULK);
630 createMissingClients(c);
631 aeMain(config.el);
632 endBenchmark("LRANGE (first 100 elements)");
633
ccb5332 Salvatore Sanfilippo more writev tests/work
authored
634 prepareForBenchmark();
635 c = createClient();
636 if (!c) exit(1);
637 c->obuf = sdscat(c->obuf,"LRANGE mylist 0 299\r\n");
638 prepareClientForReply(c,REPLY_MBULK);
639 createMissingClients(c);
640 aeMain(config.el);
641 endBenchmark("LRANGE (first 300 elements)");
642
cc30e36 Salvatore Sanfilippo benchmarking with different number of LRANGE elements. Ability to change...
authored
643 prepareForBenchmark();
644 c = createClient();
645 if (!c) exit(1);
646 c->obuf = sdscat(c->obuf,"LRANGE mylist 0 449\r\n");
647 prepareClientForReply(c,REPLY_MBULK);
648 createMissingClients(c);
649 aeMain(config.el);
650 endBenchmark("LRANGE (first 450 elements)");
651
652 prepareForBenchmark();
653 c = createClient();
654 if (!c) exit(1);
655 c->obuf = sdscat(c->obuf,"LRANGE mylist 0 599\r\n");
656 prepareClientForReply(c,REPLY_MBULK);
657 createMissingClients(c);
658 aeMain(config.el);
659 endBenchmark("LRANGE (first 600 elements)");
660
ed9b544 Salvatore Sanfilippo first commit
authored
661 printf("\n");
662 } while(config.loop);
663
664 return 0;
665 }
Something went wrong with that request. Please try again.