X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Fmemslap.c;h=5815015905d90fa7547f21a2735ee3f12ddfefe7;hb=1bd637f6eccc1064a4e19e40b14a340818d1ccf3;hp=fad016ecc8adaaac803d485172002def3a29ba8b;hpb=113160884d25c401dc352cfab093b5b7b1a4fde0;p=m6w6%2Flibmemcached diff --git a/src/memslap.c b/src/memslap.c index fad016ec..58150159 100644 --- a/src/memslap.c +++ b/src/memslap.c @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -14,6 +15,14 @@ #include "client_options.h" #include "utilities.h" #include "generator.h" +#include "execute.h" + +#define DEFAULT_INITIAL_LOAD 10000 +#define DEFAULT_EXECUTE_NUMBER 10000 +#define DEFAULT_CONCURRENCY 1 + +#define PROGRAM_NAME "memslap" +#define PROGRAM_DESCRIPTION "Generates a load against a memcached custer of servers." /* Global Thread counter */ unsigned int thread_counter; @@ -29,13 +38,17 @@ void *run_task(void *p); typedef struct conclusions_st conclusions_st; typedef struct thread_context_st thread_context_st; typedef enum { - AC_SET, - AC_GET, -} run_action; + SET_TEST, + GET_TEST, +} test_type; struct thread_context_st { - pairs_st *pairs; - run_action action; + unsigned int key_count; + pairs_st *initial_pairs; + unsigned int initial_number; + pairs_st *execute_pairs; + unsigned int execute_number; + test_type test; memcached_server_st *servers; }; @@ -50,12 +63,20 @@ struct conclusions_st { void options_parse(int argc, char *argv[]); void conclusions_print(conclusions_st *conclusion); void scheduler(memcached_server_st *servers, conclusions_st *conclusion); +pairs_st *load_create_data(memcached_server_st *servers, unsigned int number_of, + unsigned int *actual_loaded); +void flush_all(memcached_server_st *servers); static int opt_verbose= 0; -static unsigned int opt_default_pairs= 100; -static unsigned int opt_concurrency= 10; +static int opt_flush= 0; +static int opt_non_blocking_io= 0; +static int opt_tcp_nodelay= 0; +static unsigned int opt_execute_number= 0; +static unsigned int opt_createial_load= 0; +static unsigned int opt_concurrency= 0; static int opt_displayflag= 0; static char *opt_servers= NULL; +test_type opt_test= SET_TEST; int main(int argc, char *argv[]) { @@ -68,9 +89,16 @@ int main(int argc, char *argv[]) options_parse(argc, argv); if (!opt_servers) - exit(0); + { + char *temp; + + if ((temp= getenv("MEMCACHED_SERVERS"))) + opt_servers= strdup(temp); + else + exit(1); + } - servers= parse_opt_servers(opt_servers); + servers= memcached_servers_parse(opt_servers); pthread_mutex_init(&counter_mutex, NULL); pthread_cond_init(&count_threshhold, NULL); @@ -81,10 +109,10 @@ int main(int argc, char *argv[]) free(opt_servers); - (void)pthread_mutex_init(&counter_mutex, NULL); - (void)pthread_cond_init(&count_threshhold, NULL); - (void)pthread_mutex_init(&sleeper_mutex, NULL); - (void)pthread_cond_init(&sleep_threshhold, NULL); + (void)pthread_mutex_destroy(&counter_mutex); + (void)pthread_cond_destroy(&count_threshhold); + (void)pthread_mutex_destroy(&sleeper_mutex); + (void)pthread_cond_destroy(&sleep_threshhold); conclusions_print(&conclusion); memcached_server_list_free(servers); @@ -94,16 +122,21 @@ int main(int argc, char *argv[]) void scheduler(memcached_server_st *servers, conclusions_st *conclusion) { unsigned int x; + unsigned int actual_loaded; + struct timeval start_time, end_time; pthread_t mainthread; /* Thread descriptor */ pthread_attr_t attr; /* Thread attributes */ - pairs_st *pairs; + pairs_st *pairs= NULL; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pairs= pairs_generate(opt_default_pairs); + if (opt_flush) + flush_all(servers); + if (opt_createial_load) + pairs= load_create_data(servers, opt_createial_load, &actual_loaded); pthread_mutex_lock(&counter_mutex); thread_counter= 0; @@ -118,8 +151,16 @@ void scheduler(memcached_server_st *servers, conclusions_st *conclusion) context= (thread_context_st *)malloc(sizeof(thread_context_st)); context->servers= servers; - context->pairs= pairs; - context->action= AC_SET; + context->test= opt_test; + + context->initial_pairs= pairs; + context->initial_number= actual_loaded; + + if (opt_test == SET_TEST) + { + context->execute_pairs= pairs_generate(opt_execute_number); + context->execute_number= opt_execute_number; + } /* now you create the thread */ if (pthread_create(&mainthread, &attr, run_task, @@ -164,15 +205,26 @@ void scheduler(memcached_server_st *servers, conclusions_st *conclusion) void options_parse(int argc, char *argv[]) { + memcached_programs_help_st help_options[]= + { + {0}, + }; + static struct option long_options[]= { - {"version", no_argument, NULL, OPT_VERSION}, - {"help", no_argument, NULL, OPT_HELP}, - {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {"concurrency", required_argument, NULL, OPT_SLAP_CONCURRENCY}, {"debug", no_argument, &opt_verbose, OPT_DEBUG}, - {"servers", required_argument, NULL, OPT_SERVERS}, + {"execute-number", required_argument, NULL, OPT_SLAP_EXECUTE_NUMBER}, {"flag", no_argument, &opt_displayflag, OPT_FLAG}, - {"default-pairs", required_argument, NULL, OPT_SLAP_DEFAULT_PAIRS}, + {"flush", no_argument, &opt_flush, OPT_FLUSH}, + {"help", no_argument, NULL, OPT_HELP}, + {"initial-load", required_argument, NULL, OPT_SLAP_INITIAL_LOAD}, /* Number to load initially */ + {"non-blocking", no_argument, &opt_non_blocking_io, OPT_SLAP_NON_BLOCK}, + {"servers", required_argument, NULL, OPT_SERVERS}, + {"tcp-nodelay", no_argument, &opt_tcp_nodelay, OPT_SLAP_TCP_NODELAY}, + {"test", required_argument, NULL, OPT_SLAP_TEST}, + {"verbose", no_argument, &opt_verbose, OPT_VERBOSE}, + {"version", no_argument, NULL, OPT_VERSION}, {0, 0, 0, 0}, }; @@ -194,18 +246,32 @@ void options_parse(int argc, char *argv[]) opt_verbose = OPT_DEBUG; break; case OPT_VERSION: /* --version or -V */ - printf("memcache tools, memcat, v1.0\n"); - exit(0); + version_command(PROGRAM_NAME); break; case OPT_HELP: /* --help or -h */ - printf("useful help messages go here\n"); - exit(0); + help_command(PROGRAM_NAME, PROGRAM_DESCRIPTION, long_options, help_options); break; case OPT_SERVERS: /* --servers or -s */ opt_servers= strdup(optarg); break; - case OPT_SLAP_DEFAULT_PAIRS: - opt_default_pairs= strtol(optarg, (char **)NULL, 10); + case OPT_SLAP_TEST: + if (!strcmp(optarg, "get")) + opt_test= GET_TEST ; + else if (!strcmp(optarg, "set")) + opt_test= SET_TEST; + else + { + fprintf(stderr, "Your test, %s, is not a known test\n", optarg); + exit(1); + } + break; + case OPT_SLAP_CONCURRENCY: + opt_concurrency= strtol(optarg, (char **)NULL, 10); + case OPT_SLAP_EXECUTE_NUMBER: + opt_execute_number= strtol(optarg, (char **)NULL, 10); + break; + case OPT_SLAP_INITIAL_LOAD: + opt_createial_load= strtol(optarg, (char **)NULL, 10); break; case '?': /* getopt_long already printed an error message. */ @@ -214,27 +280,43 @@ void options_parse(int argc, char *argv[]) abort(); } } + + if (opt_test == GET_TEST && opt_createial_load == 0) + opt_createial_load= DEFAULT_INITIAL_LOAD; + + if (opt_execute_number == 0) + opt_execute_number= DEFAULT_EXECUTE_NUMBER; + + if (opt_concurrency == 0) + opt_concurrency= DEFAULT_CONCURRENCY; } void conclusions_print(conclusions_st *conclusion) { + printf("\tThreads connecting to servers %u\n", opt_concurrency); +#ifdef NOT_FINISHED printf("\tLoaded %u rows\n", conclusion->rows_loaded); printf("\tRead %u rows\n", conclusion->rows_read); - printf("\tTook %ld.%03ld seconds to load data\n", conclusion->load_time / 1000, - conclusion->load_time % 1000); - printf("\tTook %ld.%03ld seconds to read data\n", conclusion->read_time / 1000, - conclusion->read_time % 1000); +#endif + if (opt_test == SET_TEST) + printf("\tTook %ld.%03ld seconds to load data\n", conclusion->load_time / 1000, + conclusion->load_time % 1000); + else + printf("\tTook %ld.%03ld seconds to read data\n", conclusion->read_time / 1000, + conclusion->read_time % 1000); } void *run_task(void *p) { - unsigned int x; thread_context_st *context= (thread_context_st *)p; - memcached_return rc; memcached_st *memc; - pairs_st *pairs= context->pairs; + unsigned int value= 1; - memc= memcached_init(NULL); + memc= memcached_create(NULL); + if (opt_non_blocking_io) + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, &value); + if (opt_tcp_nodelay) + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_TCP_NODELAY, &value); memcached_server_push(memc, context->servers); @@ -246,35 +328,13 @@ void *run_task(void *p) pthread_mutex_unlock(&sleeper_mutex); /* Do Stuff */ - switch (context->action) + switch (context->test) { - case AC_SET: - for (x= 0; x < opt_default_pairs; x++) - { - rc= memcached_set(memc, pairs[x].key, pairs[x].key_length, - pairs[x].value, pairs[x].value_length, - 0, 0); - if (rc != MEMCACHED_SUCCESS) - fprintf(stderr, "Failured on insert of %.*s\n", - (unsigned int)pairs[x].key_length, pairs[x].key); - } + case SET_TEST: + execute_set(memc, context->execute_pairs, context->execute_number); break; - case AC_GET: - for (x= 0; x < opt_default_pairs; x++) - { - char *value; - size_t value_length; - uint16_t flags; - - value= memcached_get(memc, pairs[x].key, pairs[x].key_length, - &value_length, - &flags, &rc); - - if (rc != MEMCACHED_SUCCESS) - fprintf(stderr, "Failured on read of %.*s\n", - (unsigned int)pairs[x].key_length, pairs[x].key); - free(value); - } + case GET_TEST: + execute_get(memc, context->initial_pairs, context->initial_number); break; } @@ -282,9 +342,43 @@ void *run_task(void *p) thread_counter--; pthread_cond_signal(&count_threshhold); pthread_mutex_unlock(&counter_mutex); - memcached_deinit(memc); + memcached_free(memc); + if (context->execute_pairs) + pairs_free(context->execute_pairs); free(context); return NULL; } + +void flush_all(memcached_server_st *servers) +{ + memcached_st *memc; + + memc= memcached_create(NULL); + + memcached_server_push(memc, servers); + + memcached_flush(memc, 0); + + memcached_free(memc); +} + +pairs_st *load_create_data(memcached_server_st *servers, unsigned int number_of, + unsigned int *actual_loaded) +{ + memcached_st *memc; + pairs_st *pairs; + + memc= memcached_create(NULL); + /* We always used non-blocking IO for load since it is faster */ + memcached_behavior_set(memc, MEMCACHED_BEHAVIOR_NO_BLOCK, NULL ); + memcached_server_push(memc, servers); + + pairs= pairs_generate(number_of); + *actual_loaded= execute_set(memc, pairs, number_of); + + memcached_free(memc); + + return pairs; +}