X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Ftest%2Fbench%2Fsmall_io_bench_fs.cc;fp=src%2Fceph%2Fsrc%2Ftest%2Fbench%2Fsmall_io_bench_fs.cc;h=619f14d62bceb50e71faf237321701b21012f214;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/test/bench/small_io_bench_fs.cc b/src/ceph/src/test/bench/small_io_bench_fs.cc new file mode 100644 index 0000000..619f14d --- /dev/null +++ b/src/ceph/src/test/bench/small_io_bench_fs.cc @@ -0,0 +1,252 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common/Formatter.h" + +#include "bencher.h" +#include "rados_backend.h" +#include "detailed_stat_collector.h" +#include "distribution.h" +#include "global/global_init.h" +#include "os/filestore/FileStore.h" +#include "testfilestore_backend.h" +#include "common/perf_counters.h" + +namespace po = boost::program_options; +using namespace std; + +struct MorePrinting : public DetailedStatCollector::AdditionalPrinting { + CephContext *cct; + explicit MorePrinting(CephContext *cct) : cct(cct) {} + void operator()(std::ostream *out) override { + bufferlist bl; + Formatter *f = Formatter::create("json-pretty"); + cct->get_perfcounters_collection()->dump_formatted(f, 0); + f->flush(bl); + delete f; + bl.append('\0'); + *out << bl.c_str() << std::endl; + } +}; + +int main(int argc, char **argv) +{ + po::options_description desc("Allowed options"); + desc.add_options() + ("help", "produce help message") + ("num-concurrent-ops", po::value()->default_value(10), + "set number of concurrent ops") + ("num-objects", po::value()->default_value(500), + "set number of objects to use") + ("object-size", po::value()->default_value(4<<20), + "set object size") + ("io-size", po::value()->default_value(4<<10), + "set io size") + ("write-ratio", po::value()->default_value(0.75), + "set ratio of read to write") + ("duration", po::value()->default_value(0), + "set max duration, 0 for unlimited") + ("max-ops", po::value()->default_value(0), + "set max ops, 0 for unlimited") + ("seed", po::value(), + "seed") + ("num-colls", po::value()->default_value(20), + "number of collections") + ("op-dump-file", po::value()->default_value(""), + "set file for dumping op details, omit for stderr") + ("filestore-path", po::value(), + "path to filestore directory, mandatory") + ("journal-path", po::value(), + "path to journal, mandatory") + ("offset-align", po::value()->default_value(4096), + "align offset by") + ("write-infos", po::value()->default_value(false), + "write info objects with main writes") + ("sequential", po::value()->default_value(false), + "do sequential writes like rbd") + ("disable-detailed-ops", po::value()->default_value(false), + "don't dump per op stats") + ("num-writers", po::value()->default_value(1), + "num write threads") + ; + + vector ceph_option_strings; + po::variables_map vm; + try { + po::parsed_options parsed = + po::command_line_parser(argc, argv).options(desc).allow_unregistered().run(); + po::store( + parsed, + vm); + po::notify(vm); + + ceph_option_strings = po::collect_unrecognized(parsed.options, + po::include_positional); + } catch(po::error &e) { + std::cerr << e.what() << std::endl; + return 1; + } + vector ceph_options, def_args; + ceph_options.reserve(ceph_option_strings.size()); + for (vector::iterator i = ceph_option_strings.begin(); + i != ceph_option_strings.end(); + ++i) { + ceph_options.push_back(i->c_str()); + } + + auto cct = global_init( + &def_args, ceph_options, CEPH_ENTITY_TYPE_CLIENT, + CODE_ENVIRONMENT_UTILITY, + CINIT_FLAG_NO_DEFAULT_CONFIG_FILE); + common_init_finish(g_ceph_context); + g_ceph_context->_conf->apply_changes(NULL); + + if (!vm.count("filestore-path") || !vm.count("journal-path")) { + cout << "Must provide filestore-path and journal-path" << std::endl + << desc << std::endl; + return 1; + } + + if (vm.count("help")) { + cout << desc << std::endl; + return 1; + } + + rngen_t rng; + if (vm.count("seed")) + rng = rngen_t(vm["seed"].as()); + + set > ops; + ops.insert(make_pair(vm["write-ratio"].as(), Bencher::WRITE)); + ops.insert(make_pair(1-vm["write-ratio"].as(), Bencher::READ)); + + FileStore fs(g_ceph_context, vm["filestore-path"].as(), + vm["journal-path"].as()); + ObjectStore::Sequencer osr(__func__); + + if (fs.mkfs() < 0) { + cout << "mkfs failed" << std::endl; + return 1; + } + + if (fs.mount() < 0) { + cout << "mount failed" << std::endl; + return 1; + } + + ostream *detailed_ops = 0; + ofstream myfile; + if (vm["disable-detailed-ops"].as()) { + detailed_ops = 0; + } else if (vm["op-dump-file"].as().size()) { + myfile.open(vm["op-dump-file"].as().c_str()); + detailed_ops = &myfile; + } else { + detailed_ops = &cerr; + } + + ceph::shared_ptr col( + new DetailedStatCollector( + 1, new JSONFormatter, detailed_ops, &cout, + new MorePrinting(g_ceph_context))); + + cout << "Creating objects.." << std::endl; + bufferlist bl; + for (uint64_t i = 0; i < vm["object-size"].as(); ++i) { + bl.append(0); + } + + for (uint64_t num = 0; num < vm["num-colls"].as(); ++num) { + spg_t pgid(pg_t(num, 0), shard_id_t::NO_SHARD); + std::cout << "collection " << pgid << std::endl; + ObjectStore::Transaction t; + t.create_collection(coll_t(pgid), 0); + fs.apply_transaction(&osr, std::move(t)); + } + { + ObjectStore::Transaction t; + t.create_collection(coll_t(), 0); + fs.apply_transaction(&osr, std::move(t)); + } + + vector > benchers( + vm["num-writers"].as()); + for (vector >::iterator i = benchers.begin(); + i != benchers.end(); + ++i) { + set objects; + for (uint64_t num = 0; num < vm["num-objects"].as(); ++num) { + unsigned col_num = num % vm["num-colls"].as(); + spg_t pgid(pg_t(col_num, 0), shard_id_t::NO_SHARD); + stringstream obj; + obj << "obj_" << num << "_bencher_" << (i - benchers.begin()); + objects.insert(coll_t(pgid).to_str() + string("/") + obj.str()); + } + Distribution< + boost::tuple > *gen = 0; + if (vm["sequential"].as()) { + std::cout << "Using Sequential generator" << std::endl; + gen = new SequentialLoad( + objects, + vm["object-size"].as(), + vm["io-size"].as(), + new WeightedDist(rng, ops) + ); + } else { + std::cout << "Using random generator" << std::endl; + gen = new FourTupleDist( + new RandomDist(rng, objects), + new Align( + new UniformRandom( + rng, + 0, + vm["object-size"].as() - vm["io-size"].as()), + vm["offset-align"].as() + ), + new Uniform(vm["io-size"].as()), + new WeightedDist(rng, ops) + ); + } + + Bencher *bencher = new Bencher( + gen, + col, + new TestFileStoreBackend(&fs, vm["write-infos"].as()), + vm["num-concurrent-ops"].as(), + vm["duration"].as(), + vm["max-ops"].as()); + + bencher->init(objects, vm["object-size"].as(), &std::cout); + cout << "Created objects..." << std::endl; + (*i).reset(bencher); + } + + for (vector >::iterator i = benchers.begin(); + i != benchers.end(); + ++i) { + (*i)->create("bencher"); + } + for (vector >::iterator i = benchers.begin(); + i != benchers.end(); + ++i) { + (*i)->join(); + } + + fs.umount(); + if (vm["op-dump-file"].as().size()) { + myfile.close(); + } + return 0; +}