]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rados: change benchmark interface and record objects written/size to osds
authorGreg Farnum <gregf@hq.newdream.net>
Fri, 4 Dec 2009 19:06:35 +0000 (11:06 -0800)
committerGreg Farnum <gregf@hq.newdream.net>
Fri, 4 Dec 2009 23:54:28 +0000 (15:54 -0800)
src/osdc/rados_bencher.h
src/rados.cc

index bc85d8f4446e1274ca53bddecbae4068e3b7d2e1..91ed3b99b9f6f950c4c58f18932bfcc6a77687df 100644 (file)
 #include <sstream>
 
 Mutex dataLock("data mutex");
+const int OP_WRITE     = 1;
+const int OP_SEQ_READ  = 2;
+const int OP_RAND_READ = 3;
+const char *BENCH_DATA = "benchmark_write_data";
 
 struct bench_data {
   bool done; //is the benchmark is done
@@ -42,42 +46,66 @@ struct bench_data {
 int write_bench(Rados& rados, rados_pool_t pool,
                 int secondsToRun, int concurrentios, bench_data *data);
 int seq_read_bench(Rados& rados, rados_pool_t pool,
-                  int concurrentios, bench_data *data, int verify);
+                  int concurrentios, bench_data *data);
 void *status_printer(void * data_store);
 void sanitize_object_contents(bench_data *data, int length);
   
-int aio_bench(Rados& rados, rados_pool_t pool, int secondsToRun,
-             int concurrentios, int writeSize, int sequentialTest) {
-
-  char* contentsChars = new char[writeSize];
+int aio_bench(Rados& rados, rados_pool_t pool, int operation,
+             int secondsToRun, int concurrentios, int op_size) {
+  int object_size = op_size;
+  int num_objects = 0;
+  char* contentsChars = new char[op_size];
   int r = 0;
+
+  //set up the pool
+  cout << "open pool result = " << rados.open_pool("data",&pool)
+       << " pool = " << pool << std::endl;
+  
+  //get data from previous write run, if available
+  if (operation != OP_WRITE) {
+    bufferlist object_data;
+    r = rados.read(pool, BENCH_DATA, 0, object_data, sizeof(int)*2);
+    if (r <= 0) {
+      delete contentsChars;
+      if (r == -2)
+       cerr << "Must write data before running a read benchmark!" << std::endl;
+      return r;
+    }
+    bufferlist::iterator p = object_data.begin();
+    ::decode(object_size, p);
+    ::decode(num_objects, p);
+  } else {
+    object_size = op_size;
+  }
   
   dataLock.Lock();
   bench_data *data = new bench_data();
   data->done = false;
-  data->object_size = writeSize;
-  data->trans_size = writeSize; //just for now
+  data->object_size = object_size;
+  data->trans_size = op_size;
   data->in_flight = 0;
   data->started = 0;
-  data->finished = 0;
+  data->finished = num_objects;
   data->min_latency = 9999.0; // this better be higher than initial latency!
   data->max_latency = 0;
   data->avg_latency = 0;
   data->object_contents = contentsChars;
   dataLock.Unlock();
 
-
   //fill in contentsChars deterministically so we can check returns
-  sanitize_object_contents(data, writeSize);
-  //set up the pool
-  cout << "open pool result = " << rados.open_pool("data",&pool) << " pool = " << pool << std::endl;
-  
-  r = write_bench(rados, pool, secondsToRun, concurrentios, data);
-  if (r != 0) goto out;
+  sanitize_object_contents(data, data->object_size);
 
-  //check objects for consistency if requested
-  if (sequentialTest) {
-    r = seq_read_bench(rados, pool, concurrentios, data, 1);
+  if (OP_WRITE == operation) {
+    r = write_bench(rados, pool, secondsToRun, concurrentios, data);
+    if (r != 0) goto out;
+  }
+  else if (OP_SEQ_READ == operation) {
+    r = seq_read_bench(rados, pool, concurrentios, data);
+    if (r != 0) goto out;
+  }
+  else if (OP_RAND_READ == operation) {
+    cerr << "Random test not implemented yet!" << std::endl;
+    r = -1;
   }
   
  out:
@@ -223,11 +251,20 @@ int write_bench(Rados& rados, rados_pool_t pool,
        << "Average Latency:       " << data->avg_latency << std::endl
        << "Max latency:           " << data->max_latency << std::endl
        << "Min latency:           " << data->min_latency << std::endl;
+
+  //write object size/number data for read benchmarks
+  int written_objects[2];
+  written_objects[0] = data->object_size;
+  written_objects[1] = data->finished;
+  bufferlist b_write;
+  ::encode(data->object_size, b_write);
+  ::encode(data->finished, b_write);
+  rados.write(pool, BENCH_DATA, 0, b_write, sizeof(int)*2);
   return 0;
 }
 
 int seq_read_bench(Rados& rados, rados_pool_t pool,
-                  int concurrentios, bench_data *write_data, int verify) {
+                  int concurrentios, bench_data *write_data) {
   bench_data *data = new bench_data();
   data->done = false;
   data->object_size = write_data->object_size;
@@ -315,15 +352,11 @@ int seq_read_bench(Rados& rados, rados_pool_t pool,
     dataLock.Lock();
     ++data->started;
     ++data->in_flight;
+    snprintf(data->object_contents, data->object_size, "I'm the %dth object!", i);
     dataLock.Unlock();
-    if (verify) {
-      dataLock.Lock();
-      snprintf(data->object_contents, data->object_size, "I'm the %dth object!", i);
-      dataLock.Unlock();
-      if (memcmp(data->object_contents, cur_contents->c_str(), data->object_size) != 0) {
-       cerr << name[slot] << " is not correct!";
-       ++errors;
-      }
+    if (memcmp(data->object_contents, cur_contents->c_str(), data->object_size) != 0) {
+      cerr << name[slot] << " is not correct!";
+      ++errors;
     }
     delete name[slot];
     name[slot] = newName;
@@ -348,16 +381,12 @@ int seq_read_bench(Rados& rados, rados_pool_t pool,
     ++data->finished;
     data->avg_latency = total_latency / data->finished;
     --data->in_flight;
-    dataLock.Unlock();
     completions[slot]-> release();
-    if (verify) {
-      dataLock.Lock();
-      snprintf(data->object_contents, data->object_size, "I'm the %dth object!", data->finished-1);
-      dataLock.Unlock();
-      if (memcmp(data->object_contents, contents[slot]->c_str(), data->object_size) != 0) {
-       cerr << name[slot] << " is not correct!" << std::endl;
-       ++errors;
-      }
+    snprintf(data->object_contents, data->object_size, "I'm the %dth object!", data->finished-1);
+    dataLock.Unlock();
+    if (memcmp(data->object_contents, contents[slot]->c_str(), data->object_size) != 0) {
+      cerr << name[slot] << " is not correct!" << std::endl;
+      ++errors;
     }
     delete name[slot];
     delete contents[slot];
index 03a3435159b13e2558406d9bb53a07c3e6354673..48613cc85bd758fc46508255d1e8f17e256134fa 100644 (file)
@@ -49,8 +49,8 @@ void usage()
   cerr << "   mksnap foo  -- create snap 'foo'\n";
   cerr << "   rmsnap foo  -- remove snap 'foo'\n\n";
 
-  cerr << "   bench <seconds> [-t concurrentwrites] [-b writesize] [verify]\n";
-  cerr << "              default is 16 concurrent IOs and 4 MB writes size\n\n";
+  cerr << "   bench <seconds> write|seq|rand [-t concurrent_operations] [-b op_size]\n";
+  cerr << "              default is 16 concurrent IOs and 4 MB op size\n\n";
 
   cerr << "Options:\n";
   cerr << "   -p pool\n";
@@ -84,7 +84,7 @@ int main(int argc, const char **argv)
   const char *pool = 0;
  
   int concurrent_ios = 16;
-  int write_size = 1 << 22;
+  int op_size = 1 << 22;
 
   const char *snapname = 0;
   rados_snap_t snapid = CEPH_NOSNAP;
@@ -101,7 +101,7 @@ int main(int argc, const char **argv)
     } else if (CONF_ARG_EQ("concurrent-ios", 't')) {
       CONF_SAFE_SET_ARG_VAL(&concurrent_ios, OPT_INT);
     } else if (CONF_ARG_EQ("block-size", 'b')) {
-      CONF_SAFE_SET_ARG_VAL(&write_size, OPT_INT);
+      CONF_SAFE_SET_ARG_VAL(&op_size, OPT_INT);
     } else if (args[i][0] == '-' && nargs.empty()) {
       cerr << "unrecognized option " << args[i] << std::endl;
       usage();
@@ -333,17 +333,19 @@ int main(int argc, const char **argv)
   }
   
   else if (strcmp(nargs[0], "bench") == 0) {
-    if (!pool || nargs.size() < 2)
+    if (!pool || nargs.size() < 3)
       usage();
     int seconds = atoi(nargs[1]);
-    int verify = 0;
-    for (unsigned i=2; i<nargs.size(); i++) {
-      if (strcmp(nargs[i], "verify") == 0)
-       verify = 1;
-      else
-       usage();
-    }
-    ret = aio_bench(rados, p, seconds, concurrent_ios, write_size, verify);
+    int operation = 0;
+    if (strcmp(nargs[2], "write") == 0)
+      operation = OP_WRITE;
+    else if (strcmp(nargs[2], "seq") == 0)
+      operation = OP_SEQ_READ;
+    else if (strcmp(nargs[2], "rand") == 0)
+      operation = OP_RAND_READ;
+    else
+      usage();
+    ret = aio_bench(rados, p, operation, seconds, concurrent_ios, op_size);
     if (ret != 0)
       cerr << "error during benchmark: " << ret << std::endl;
   }