]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/bench/small_io_bench_rbd.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
3 #include <boost/lexical_cast.hpp>
4 #include <boost/program_options/option.hpp>
5 #include <boost/program_options/options_description.hpp>
6 #include <boost/program_options/variables_map.hpp>
7 #include <boost/program_options/cmdline.hpp>
8 #include <boost/program_options/parsers.hpp>
15 #include "common/Formatter.h"
18 #include "rbd_backend.h"
19 #include "detailed_stat_collector.h"
20 #include "distribution.h"
22 namespace po
= boost::program_options
;
25 int main(int argc
, char **argv
)
27 po::options_description
desc("Allowed options");
29 ("help", "produce help message")
30 ("num-concurrent-ops", po::value
<unsigned>()->default_value(10),
31 "set number of concurrent ops")
32 ("num-images", po::value
<unsigned>()->default_value(2),
33 "set number of rbd images to use")
34 ("image-size", po::value
<unsigned>()->default_value(4096),
35 "set image size in megabytes")
36 ("order", po::value
<unsigned>()->default_value(22),
37 "set log_2(object size)")
38 ("io-size", po::value
<unsigned>()->default_value(4<<10),
40 ("write-ratio", po::value
<double>()->default_value(0.25),
41 "set ratio of read to write")
42 ("duration", po::value
<unsigned>()->default_value(0),
43 "set max duration, 0 for unlimited")
44 ("max-ops", po::value
<unsigned>()->default_value(0),
45 "set max ops, 0 for unlimited")
46 ("seed", po::value
<unsigned>(),
48 ("ceph-client-id", po::value
<string
>()->default_value("admin"),
50 ("pool-name", po::value
<string
>()->default_value("data"),
52 ("op-dump-file", po::value
<string
>()->default_value(""),
53 "set file for dumping op details, omit for stderr")
54 ("offset-align", po::value
<unsigned>()->default_value(4096),
56 ("sequential", po::value
<bool>()->default_value(false),
57 "use sequential access pattern")
58 ("disable-detailed-ops", po::value
<bool>()->default_value(false),
59 "don't dump per op stats")
63 po::store(po::parse_command_line(argc
, argv
, desc
), vm
);
66 if (vm
.count("help")) {
67 cout
<< desc
<< std::endl
;
72 char hostname_cstr
[100];
73 gethostname(hostname_cstr
, 100);
75 hostpid
<< hostname_cstr
<< getpid() << "-";
76 prefix
= hostpid
.str();
78 set
<string
> image_names
;
79 for (unsigned i
= 0; i
< vm
["num-images"].as
<unsigned>();
82 name
<< prefix
<< "-image_" << i
;
83 image_names
.insert(name
.str());
88 rng
= rngen_t(vm
["seed"].as
<unsigned>());
90 set
<pair
<double, Bencher::OpType
> > ops
;
91 ops
.insert(make_pair(vm
["write-ratio"].as
<double>(), Bencher::WRITE
));
92 ops
.insert(make_pair(1-vm
["write-ratio"].as
<double>(), Bencher::READ
));
94 librados::Rados rados
;
95 librados::IoCtx ioctx
;
96 int r
= rados
.init(vm
["ceph-client-id"].as
<string
>().c_str());
98 cerr
<< "error in init r=" << r
<< std::endl
;
101 r
= rados
.conf_read_file(NULL
);
103 cerr
<< "error in conf_read_file r=" << r
<< std::endl
;
106 r
= rados
.conf_parse_env(NULL
);
108 cerr
<< "error in conf_parse_env r=" << r
<< std::endl
;
113 cerr
<< "error in connect r=" << r
<< std::endl
;
116 r
= rados
.ioctx_create(vm
["pool-name"].as
<string
>().c_str(), ioctx
);
118 cerr
<< "error in ioctx_create r=" << r
<< std::endl
;
122 ostream
*detailed_ops
= 0;
124 if (vm
["disable-detailed-ops"].as
<bool>()) {
126 } else if (vm
["op-dump-file"].as
<string
>().size()) {
127 myfile
.open(vm
["op-dump-file"].as
<string
>().c_str());
128 detailed_ops
= &myfile
;
130 detailed_ops
= &cerr
;
135 map
<string
, ceph::shared_ptr
<librbd::Image
> > images
;
136 int order
= vm
["order"].as
<unsigned>();
137 uint64_t image_size
= ((uint64_t)vm
["image-size"].as
<unsigned>()) << 20;
138 for (set
<string
>::const_iterator i
= image_names
.begin();
139 i
!= image_names
.end(); ++i
) {
140 r
= rbd
.create(ioctx
, i
->c_str(), image_size
, &order
);
142 cerr
<< "error creating image " << *i
<< " r=" << r
<< std::endl
;
145 ceph::shared_ptr
<librbd::Image
> image(new librbd::Image());
146 r
= rbd
.open(ioctx
, *image
, i
->c_str());
148 cerr
<< "error opening image " << *i
<< " r=" << r
<< std::endl
;
155 boost::tuple
<string
, uint64_t, uint64_t, Bencher::OpType
> > *gen
= 0;
156 if (vm
["sequential"].as
<bool>()) {
157 std::cout
<< "Using Sequential generator" << std::endl
;
158 gen
= new SequentialLoad(
161 vm
["io-size"].as
<unsigned>(),
162 new WeightedDist
<Bencher::OpType
>(rng
, ops
)
165 std::cout
<< "Using random generator" << std::endl
;
166 gen
= new FourTupleDist
<string
, uint64_t, uint64_t, Bencher::OpType
>(
167 new RandomDist
<string
>(rng
, image_names
),
172 image_size
- vm
["io-size"].as
<unsigned>()),
173 vm
["offset-align"].as
<unsigned>()
175 new Uniform(vm
["io-size"].as
<unsigned>()),
176 new WeightedDist
<Bencher::OpType
>(rng
, ops
)
182 new DetailedStatCollector(1, new JSONFormatter
, detailed_ops
, &cout
),
183 new RBDBackend(&images
),
184 vm
["num-concurrent-ops"].as
<unsigned>(),
185 vm
["duration"].as
<unsigned>(),
186 vm
["max-ops"].as
<unsigned>());
191 for (set
<string
>::const_iterator i
= image_names
.begin();
192 i
!= image_names
.end(); ++i
) {
193 rbd
.remove(ioctx
, i
->c_str());
196 if (vm
["op-dump-file"].as
<string
>().size()) {