From af10789beee8b48203c96eed3cac8cd685a663ec Mon Sep 17 00:00:00 2001 From: PCzhangPC Date: Fri, 15 Sep 2017 14:21:07 +0800 Subject: [PATCH] rbd:introduce rbd bench readwrite/rw(for read and write mix) test 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 --- src/tools/rbd/action/Bench.cc | 75 ++++++++++++++++++++++++++++------- 1 file changed, 61 insertions(+), 14 deletions(-) diff --git a/src/tools/rbd/action/Bench.cc b/src/tools/rbd/action/Bench.cc index 144e9d1dd0c18..2ff851e172a83 100644 --- a/src/tools/rbd/action/Bench.cc +++ b/src/tools/rbd/action/Bench.cc @@ -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(), "IO size (in B/K/M/G/T) [default: 4K]") ("io-threads", po::value(), "ios in flight [default: 16]") ("io-total", po::value(), "total size for IO (in B/K/M/G/T) [default: 1G]") - ("io-pattern", po::value(), "IO pattern (rand or seq) [default: seq]"); + ("io-pattern", po::value(), "IO pattern (rand or seq) [default: seq]") + ("rw-mix-read", po::value(), "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()->required(), "IO type (read or write)"); + ("io-type", po::value()->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(); + } 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; -- 2.39.5