]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rbd:introduce rbd bench readwrite/rw(for read and write mix) test
authorPCzhangPC <pengcheng.zhang@easystack.cn>
Fri, 15 Sep 2017 06:21:07 +0000 (14:21 +0800)
committerPCzhangPC <pengcheng.zhang@easystack.cn>
Fri, 15 Sep 2017 06:21:07 +0000 (14:21 +0800)
we can do rbd bench readwrite/rw(for read and write mix) test in this commit. we can also use 'rw--mix-read' to declare the read proportion in rw test(default 50 ,meaning 50%).

Signed-off-by: PCzhangPC <pengcheng.zhang@easystack.cn>
src/tools/rbd/action/Bench.cc

index 144e9d1dd0c188c3e30cb7568052836fbf85a958..2ff851e172a836ee42c23caae5e1bd944a8f212c 100644 (file)
@@ -26,6 +26,7 @@ namespace {
 enum io_type_t {
   IO_TYPE_READ = 0,
   IO_TYPE_WRITE,
+  IO_TYPE_RW,
 
   IO_TYPE_NUM,
 };
@@ -65,6 +66,8 @@ io_type_t get_io_type(string io_type_string) {
     return IO_TYPE_READ;
   else if (io_type_string == "write")
     return IO_TYPE_WRITE;
+  else if (io_type_string == "readwrite" || io_type_string == "rw")
+    return IO_TYPE_RW;
   else
     return IO_TYPE_NUM;
 }
@@ -117,15 +120,14 @@ struct rbd_bencher {
       io_type(io_type),
       io_size(io_size)
   {
-    if (io_type == IO_TYPE_WRITE) {
+    if (io_type == IO_TYPE_WRITE || io_type == IO_TYPE_RW) {
       bufferptr bp(io_size);
       memset(bp.c_str(), rand() & 0xff, io_size);
       write_bl.push_back(bp);
     }
   }
-
-
-  void start_io(int max, uint64_t off, uint64_t len, int op_flags)
+    
+  void start_io(int max, uint64_t off, uint64_t len, int op_flags, bool read_flag)
   {
     {
       Mutex::Locker l(lock);
@@ -133,17 +135,15 @@ struct rbd_bencher {
     }
 
     librbd::RBD::AioCompletion *c;
-    if (io_type == IO_TYPE_READ) {
+    if (read_flag) {
       bufferlist *read_bl = new bufferlist();
       c = new librbd::RBD::AioCompletion((void *)(new bencher_completer(this, read_bl)),
                                         rbd_bencher_completion);
       image->aio_read2(off, len, *read_bl, c, op_flags);
-    } else if (io_type == IO_TYPE_WRITE) {
+    } else {
       c = new librbd::RBD::AioCompletion((void *)(new bencher_completer(this, NULL)),
                                         rbd_bencher_completion);
       image->aio_write2(off, len, write_bl, c, op_flags);
-    } else {
-      assert(0 == "Invalid io_type");
     }
   }
 
@@ -180,9 +180,19 @@ void rbd_bencher_completion(void *vc, void *pc)
   delete bc;
 }
 
+bool should_read(uint64_t read_proportion)
+{
+  uint64_t rand_num = rand() % 100;
+
+  if (rand_num < read_proportion)
+    return true;
+  else
+    return false;
+}
+
 int do_bench(librbd::Image& image, io_type_t io_type,
                   uint64_t io_size, uint64_t io_threads,
-                  uint64_t io_bytes, bool random)
+                  uint64_t io_bytes, bool random, uint64_t read_proportion)
 {
   uint64_t size = 0;
   image.size(&size);
@@ -200,7 +210,8 @@ int do_bench(librbd::Image& image, io_type_t io_type,
   rbd_bencher b(&image, io_type, io_size);
 
   std::cout << "bench "
-       << " type " << (io_type == IO_TYPE_READ ? "read" : "write")
+       << " type " << (io_type == IO_TYPE_READ ? "read" :
+                       io_type == IO_TYPE_WRITE ? "write" : "readwrite")
        << " io_size " << io_size
        << " io_threads " << io_threads
        << " bytes " << io_bytes
@@ -251,12 +262,16 @@ int do_bench(librbd::Image& image, io_type_t io_type,
 
   printf("  SEC       OPS   OPS/SEC   BYTES/SEC\n");
   uint64_t off;
+  int read_ops = 0;
+  int write_ops = 0;
 
   for (off = 0; off < io_bytes; ) {
     i = 0;
     while (i < io_threads && off < io_bytes) {
+      bool read_flag = should_read(read_proportion);
+
       b.wait_for(io_threads - 1);
-      b.start_io(io_threads, thread_offset[i], io_size, op_flags);
+      b.start_io(io_threads, thread_offset[i], io_size, op_flags, read_flag);
 
       if (random) {
         thread_offset[i] = (rand() % (size / io_size)) * io_size;
@@ -271,6 +286,11 @@ int do_bench(librbd::Image& image, io_type_t io_type,
 
       ++cur_ios;
       cur_off += io_size;
+
+      if (read_flag)
+        read_ops++;
+      else
+        write_ops++;
     }
 
     utime_t now = ceph_clock_now();
@@ -306,6 +326,14 @@ int do_bench(librbd::Image& image, io_type_t io_type,
   printf("elapsed: %5d  ops: %8d  ops/sec: %8.2lf  bytes/sec: %8.2lf\n",
          (int)elapsed, ios, (double)ios / elapsed, (double)off / elapsed);
 
+  if (io_type == IO_TYPE_RW) {
+    printf("read_ops: %5d   read_ops/sec: %8.2lf   read_bytes/sec: %8.2lf\n",
+           read_ops, (double)read_ops / elapsed, (double)read_ops * io_size / elapsed);
+
+    printf("write_ops: %5d   write_ops/sec: %8.2lf   write_bytes/sec: %8.2lf\n",
+           write_ops, (double)write_ops / elapsed, (double)write_ops * io_size / elapsed);
+  }
+
   return 0;
 }
 
@@ -317,7 +345,8 @@ void add_bench_common_options(po::options_description *positional,
     ("io-size", po::value<Size>(), "IO size (in B/K/M/G/T) [default: 4K]")
     ("io-threads", po::value<uint32_t>(), "ios in flight [default: 16]")
     ("io-total", po::value<Size>(), "total size for IO (in B/K/M/G/T) [default: 1G]")
-    ("io-pattern", po::value<IOPattern>(), "IO pattern (rand or seq) [default: seq]");
+    ("io-pattern", po::value<IOPattern>(), "IO pattern (rand or seq) [default: seq]")
+    ("rw-mix-read", po::value<uint64_t>(), "read proportion in readwrite (<= 100) [default: 50]");
 }
 
 void get_arguments_for_write(po::options_description *positional,
@@ -330,7 +359,7 @@ void get_arguments_for_bench(po::options_description *positional,
   add_bench_common_options(positional, options);
 
   options->add_options()
-    ("io-type", po::value<IOType>()->required(), "IO type (read or write)");
+    ("io-type", po::value<IOType>()->required(), "IO type (read , write, or readwrite(rw))");
 }
 
 int bench_execute(const po::variables_map &vm, io_type_t bench_io_type) {
@@ -385,6 +414,24 @@ int bench_execute(const po::variables_map &vm, io_type_t bench_io_type) {
     bench_random = false;
   }
 
+  uint64_t bench_read_proportion;
+  if (bench_io_type == IO_TYPE_READ) {
+    bench_read_proportion = 100;
+  } else if (bench_io_type == IO_TYPE_WRITE) {
+    bench_read_proportion = 0;
+  } else {
+    if (vm.count("rw-mix-read")) {
+      bench_read_proportion = vm["rw-mix-read"].as<uint64_t>();
+    } else {
+      bench_read_proportion = 50;
+    }
+
+    if (bench_read_proportion > 100) {
+      std::cerr << "rbd: --rw-mix-read should not be larger than 100." << std::endl;
+      return -EINVAL;
+    }
+  }
+
   librados::Rados rados;
   librados::IoCtx io_ctx;
   librbd::Image image;
@@ -395,7 +442,7 @@ int bench_execute(const po::variables_map &vm, io_type_t bench_io_type) {
   }
 
   r = do_bench(image, bench_io_type, bench_io_size, bench_io_threads,
-                    bench_bytes, bench_random);
+                    bench_bytes, bench_random, bench_read_proportion);
   if (r < 0) {
     std::cerr << "bench failed: " << cpp_strerror(r) << std::endl;
     return r;