]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
Make rados/rest bench work for multiple write instances without metadata conflict.
authorGuang Yang <yguang@caughtrealize-dl-vm0.peking.corp.yahoo.com>
Tue, 15 Apr 2014 07:48:37 +0000 (07:48 +0000)
committerGuang Yang <yguang@caughtrealize-dl-vm0.peking.corp.yahoo.com>
Tue, 15 Apr 2014 07:48:37 +0000 (07:48 +0000)
Signed-off-by: Guang Yang <yguang@yahoo-inc.com>
src/common/obj_bencher.cc
src/common/obj_bencher.h
src/tools/rados/rados.cc
src/tools/rest_bench.cc

index 70675995930dc3696a8331f86732afa19bd96ec5..f2f50d0045c281a46e14f48e191df908e1f4c250 100644 (file)
@@ -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;
index b87821a7d5afa6a6953132c0e3c4d7ee7e1b73c5..216e265ba6aac446410282cd37fcee0bdd973a5c 100644 (file)
@@ -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;
index caed62bd4ad692ef889078f7c9e9846e14305562..e281006babb6b806e6c418bb3d0bf415630ab173 100644 (file)
@@ -86,10 +86,13 @@ void usage(ostream& out)
 "   rollback <obj-name> <snap-name>  roll back object to snap <snap-name>\n"
 "\n"
 "   listsnaps <obj-name>             list the snapshots of this object\n"
-"   bench <seconds> write|seq|rand [-t concurrent_operations] [--no-cleanup]\n"
+"   bench <seconds> 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 <prefix>                 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 <obj-name>          list the keys in the object map\n"
 "   listomapvals <obj-name>          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)) {
index feea4de49321f67e84f7138e1059769c28e38f16..467361a7b50c0e45b049fc3f5c6fb6ecbdf48b78 100644 (file)
@@ -36,7 +36,7 @@ void usage(ostream& out)
 {
   out <<                                       \
 "usage: rest-bench [options] <write|seq>\n"
-"       rest-bench [options] cleanup <prefix>\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;
     }