From: Guang Yang Date: Tue, 15 Apr 2014 07:48:37 +0000 (+0000) Subject: Make rados/rest bench work for multiple write instances without metadata conflict. X-Git-Tag: v0.80-rc1~33^2~1 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=308758b7878c48ab64caf71ff646e057c2c1c5aa;p=ceph.git Make rados/rest bench work for multiple write instances without metadata conflict. Signed-off-by: Guang Yang --- diff --git a/src/common/obj_bencher.cc b/src/common/obj_bencher.cc index 70675995930d..f2f50d0045c2 100644 --- a/src/common/obj_bencher.cc +++ b/src/common/obj_bencher.cc @@ -51,20 +51,6 @@ static std::string generate_object_name(int objnum, int pid = 0) return oss.str(); } -static std::string generate_metadata_name(int pid = 0) -{ - if (!pid) - pid = getpid(); - - char hostname[30]; - gethostname(hostname, sizeof(hostname)-1); - hostname[sizeof(hostname)-1] = 0; - - std::ostringstream oss; - oss << BENCH_PREFIX << "_" << hostname << "_" << pid << "_metadata"; - return oss.str(); -} - static void sanitize_object_contents (bench_data *data, int length) { memset(data->object_contents, 'z', length); } @@ -167,15 +153,18 @@ void *ObjBencher::status_printer(void *_bencher) { int ObjBencher::aio_bench( int operation, int secondsToRun, int maxObjectsToCreate, - int concurrentios, int op_size, bool cleanup) { + int concurrentios, int op_size, bool cleanup, const char* run_name) { int object_size = op_size; int num_objects = 0; int r = 0; int prevPid = 0; + // default metadata object is used if user does not specify one + const std::string run_name_meta = (run_name == NULL ? BENCH_LASTRUN_METADATA : std::string(run_name)); + //get data from previous write run, if available if (operation != OP_WRITE) { - r = fetch_bench_metadata(BENCH_LASTRUN_METADATA, &object_size, &num_objects, &prevPid); + r = fetch_bench_metadata(run_name_meta, &object_size, &num_objects, &prevPid); if (r < 0) { if (r == -ENOENT) cerr << "Must write data before running a read benchmark!" << std::endl; @@ -205,7 +194,7 @@ int ObjBencher::aio_bench( sanitize_object_contents(&data, data.object_size); if (OP_WRITE == operation) { - r = write_bench(secondsToRun, maxObjectsToCreate, concurrentios); + r = write_bench(secondsToRun, maxObjectsToCreate, concurrentios, run_name_meta); if (r != 0) goto out; } else if (OP_SEQ_READ == operation) { @@ -218,7 +207,7 @@ int ObjBencher::aio_bench( } if (OP_WRITE == operation && cleanup) { - r = fetch_bench_metadata(BENCH_LASTRUN_METADATA, &object_size, &num_objects, &prevPid); + r = fetch_bench_metadata(run_name_meta, &object_size, &num_objects, &prevPid); if (r < 0) { if (r == -ENOENT) cerr << "Should never happen: bench metadata missing for current run!" << std::endl; @@ -229,11 +218,8 @@ int ObjBencher::aio_bench( if (r != 0) goto out; // lastrun file - r = sync_remove(BENCH_LASTRUN_METADATA); + r = sync_remove(run_name_meta); if (r != 0) goto out; - - // prefix-based file - r = sync_remove(generate_metadata_name()); } out: @@ -299,7 +285,7 @@ int ObjBencher::fetch_bench_metadata(const std::string& metadata_file, int* obje } int ObjBencher::write_bench(int secondsToRun, int maxObjectsToCreate, - int concurrentios) { + int concurrentios, const string& run_name_meta) { if (maxObjectsToCreate > 0 && concurrentios > maxObjectsToCreate) concurrentios = maxObjectsToCreate; out(cout) << "Maintaining " << concurrentios << " concurrent writes of " @@ -480,11 +466,8 @@ int ObjBencher::write_bench(int secondsToRun, int maxObjectsToCreate, ::encode(data.finished, b_write); ::encode(getpid(), b_write); - // lastrun file - sync_write(BENCH_LASTRUN_METADATA, b_write, sizeof(int)*3); - - // PID-specific run - sync_write(generate_metadata_name(), b_write, sizeof(int)*3); + // persist meta-data for further cleanup or read + sync_write(run_name_meta, b_write, sizeof(int)*3); completions_done(); @@ -869,19 +852,19 @@ int ObjBencher::rand_read_bench(int seconds_to_run, int num_objects, int concurr return -5; } -int ObjBencher::clean_up(const std::string& prefix, int concurrentios) { +int ObjBencher::clean_up(const char* prefix, int concurrentios, const char* run_name) { int r = 0; int object_size; int num_objects; int prevPid; - std::string metadata_name = prefix; - metadata_name.append("_metadata"); + // default meta object if user does not specify one + const std::string run_name_meta = (run_name == NULL ? BENCH_LASTRUN_METADATA : std::string(run_name)); - r = fetch_bench_metadata(metadata_name, &object_size, &num_objects, &prevPid); + r = fetch_bench_metadata(run_name_meta, &object_size, &num_objects, &prevPid); if (r < 0) { // if the metadata file is not found we should try to do a linear search on the prefix - if (r == -ENOENT) { + if (r == -ENOENT && prefix != NULL) { return clean_up_slow(prefix, concurrentios); } else { @@ -892,7 +875,7 @@ int ObjBencher::clean_up(const std::string& prefix, int concurrentios) { r = clean_up(num_objects, prevPid, concurrentios); if (r != 0) return r; - r = sync_remove(metadata_name); + r = sync_remove(run_name_meta); if (r != 0) return r; return 0; diff --git a/src/common/obj_bencher.h b/src/common/obj_bencher.h index b87821a7d5af..216e265ba6aa 100644 --- a/src/common/obj_bencher.h +++ b/src/common/obj_bencher.h @@ -63,7 +63,7 @@ protected: int fetch_bench_metadata(const std::string& metadata_file, int* object_size, int* num_objects, int* prevPid); - int write_bench(int secondsToRun, int maxObjects, int concurrentios); + int write_bench(int secondsToRun, int maxObjects, int concurrentios, const string& run_name_meta); int seq_read_bench(int secondsToRun, int concurrentios, int num_objects, int writePid); int rand_read_bench(int secondsToRun, int num_objects, int concurrentios, int writePid); @@ -97,8 +97,8 @@ public: virtual ~ObjBencher() {} int aio_bench( int operation, int secondsToRun, int maxObjectsToCreate, - int concurrentios, int op_size, bool cleanup); - int clean_up(const std::string& prefix, int concurrentios); + int concurrentios, int op_size, bool cleanup, const char* run_name); + int clean_up(const char* prefix, int concurrentios, const char* run_name); void set_show_time(bool dt) { show_time = dt; diff --git a/src/tools/rados/rados.cc b/src/tools/rados/rados.cc index caed62bd4ad6..e281006babb6 100644 --- a/src/tools/rados/rados.cc +++ b/src/tools/rados/rados.cc @@ -86,10 +86,13 @@ void usage(ostream& out) " rollback roll back object to snap \n" "\n" " listsnaps list the snapshots of this object\n" -" bench write|seq|rand [-t concurrent_operations] [--no-cleanup]\n" +" bench write|seq|rand [-t concurrent_operations] [--no-cleanup] [--run-name run_name]\n" " default is 16 concurrent IOs and 4 MB ops\n" " default is to clean up after write benchmark\n" -" cleanup clean up a previous benchmark operation\n" +" default run-name is 'benchmark_last_metadata'\n" +" cleanup [--run-name run_name] [--prefix prefix]\n" +" clean up a previous benchmark operation\n" +" default run-name is 'benchmark_last_metadata'\n" " load-gen [options] generate load on the cluster\n" " listomapkeys list the keys in the object map\n" " listomapvals list the keys and vals in the object map \n" @@ -1196,6 +1199,9 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, bool show_time = false; + const char* run_name = NULL; + const char* prefix = NULL; + Formatter *formatter = NULL; bool pretty_format = false; @@ -1230,6 +1236,14 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, if (i != opts.end()) { concurrent_ios = strtol(i->second.c_str(), NULL, 10); } + i = opts.find("run-name"); + if (i != opts.end()) { + run_name = i->second.c_str(); + } + i = opts.find("prefix"); + if (i != opts.end()) { + prefix = i->second.c_str(); + } i = opts.find("block-size"); if (i != opts.end()) { op_size = strtol(i->second.c_str(), NULL, 10); @@ -2205,16 +2219,15 @@ static int rados_tool_common(const std::map < std::string, std::string > &opts, RadosBencher bencher(g_ceph_context, rados, io_ctx); bencher.set_show_time(show_time); ret = bencher.aio_bench(operation, seconds, num_objs, - concurrent_ios, op_size, cleanup); + concurrent_ios, op_size, cleanup, run_name); if (ret != 0) cerr << "error during benchmark: " << ret << std::endl; } else if (strcmp(nargs[0], "cleanup") == 0) { - if (!pool_name || nargs.size() < 2) + if (!pool_name) usage_exit(); - const char *prefix = nargs[1]; RadosBencher bencher(g_ceph_context, rados, io_ctx); - ret = bencher.clean_up(prefix, concurrent_ios); + ret = bencher.clean_up(prefix, concurrent_ios, run_name); if (ret != 0) cerr << "error during cleanup: " << ret << std::endl; } @@ -2562,6 +2575,10 @@ int main(int argc, const char **argv) opts["show-time"] = "true"; } else if (ceph_argparse_flag(args, i, "--no-cleanup", (char*)NULL)) { opts["no-cleanup"] = "true"; + } else if (ceph_argparse_witharg(args, i, &val, "--run-name", (char*)NULL)) { + opts["run-name"] = val; + } else if (ceph_argparse_witharg(args, i, &val, "--prefix", (char*)NULL)) { + opts["prefix"] = val; } else if (ceph_argparse_witharg(args, i, &val, "-p", "--pool", (char*)NULL)) { opts["pool"] = val; } else if (ceph_argparse_witharg(args, i, &val, "--target-pool", (char*)NULL)) { diff --git a/src/tools/rest_bench.cc b/src/tools/rest_bench.cc index feea4de49321..467361a7b50c 100644 --- a/src/tools/rest_bench.cc +++ b/src/tools/rest_bench.cc @@ -36,7 +36,7 @@ void usage(ostream& out) { out << \ "usage: rest-bench [options] \n" -" rest-bench [options] cleanup \n" +" rest-bench [options] cleanup [--run-name run_name] [--prefix prefix]\n" "BENCHMARK OPTIONS\n" " --seconds\n" " benchmak length (default: 60)\n" @@ -678,6 +678,8 @@ int main(int argc, const char **argv) bool show_time = false; bool cleanup = true; + const char* run_name = NULL; + const char* prefix = NULL; for (i = args.begin(); i != args.end(); ) { @@ -722,6 +724,10 @@ int main(int argc, const char **argv) } } else if (ceph_argparse_witharg(args, i, &val, "-t", "--concurrent-ios", (char*)NULL)) { concurrent_ios = strtol(val.c_str(), NULL, 10); + } else if (ceph_argparse_witharg(args, i, &val, "--run-name", (char*)NULL)) { + run_name = val.c_str(); + } else if (ceph_argparse_witharg(args, i, &val, "--prefix", (char*)NULL)) { + prefix = val.c_str(); } else if (ceph_argparse_witharg(args, i, &val, "--seconds", (char*)NULL)) { seconds = strtol(val.c_str(), NULL, 10); } else if (ceph_argparse_witharg(args, i, &val, "-b", "--block-size", (char*)NULL)) { @@ -740,7 +746,6 @@ int main(int argc, const char **argv) if (args.empty()) usage_exit(); int operation = 0; - const char *prefix = NULL; if (strcmp(args[0], "write") == 0) operation = OP_WRITE; else if (strcmp(args[0], "seq") == 0) @@ -748,10 +753,7 @@ int main(int argc, const char **argv) else if (strcmp(args[0], "rand") == 0) operation = OP_RAND_READ; else if (strcmp(args[0], "cleanup") == 0) { - if (args.size() < 2) - usage_exit(); operation = OP_CLEANUP; - prefix = args[1]; } else usage_exit(); @@ -784,12 +786,12 @@ int main(int argc, const char **argv) } if (operation == OP_CLEANUP) { - ret = bencher.clean_up(prefix, concurrent_ios); + ret = bencher.clean_up(prefix, concurrent_ios, run_name); if (ret != 0) cerr << "error during cleanup: " << ret << std::endl; } else { ret = bencher.aio_bench(operation, seconds, 0, - concurrent_ios, op_size, cleanup); + concurrent_ios, op_size, cleanup, run_name); if (ret != 0) { cerr << "error during benchmark: " << ret << std::endl; }