]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/objectstore/ObjectStoreTransactionBenchmark.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2014 UnitedStack <haomai@unitedstack.com>
8 * Author: Haomai Wang <haomaiwang@gmail.com>
10 * This is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License version 2.1, as published by the Free Software
13 * Foundation. See file COPYING.
24 #include "common/ceph_argparse.h"
25 #include "common/debug.h"
26 #include "common/Cycles.h"
27 #include "global/global_init.h"
28 #include "os/ObjectStore.h"
32 ObjectStore::Transaction t
;
38 Tick(): ticks(0), count(0) {}
39 void add(uint64_t a
) {
44 static Tick write_ticks
, setattr_ticks
, omap_setkeys_ticks
, omap_rmkeys_ticks
;
45 static Tick encode_ticks
, decode_ticks
, iterate_ticks
;
47 void write(coll_t cid
, const ghobject_t
& oid
, uint64_t off
, uint64_t len
,
48 const bufferlist
& data
) {
49 uint64_t start_time
= Cycles::rdtsc();
50 t
.write(cid
, oid
, off
, len
, data
);
51 write_ticks
.add(Cycles::rdtsc() - start_time
);
53 void setattr(coll_t cid
, const ghobject_t
& oid
, const string
&name
,
55 uint64_t start_time
= Cycles::rdtsc();
56 t
.setattr(cid
, oid
, name
, val
);
57 setattr_ticks
.add(Cycles::rdtsc() - start_time
);
59 void omap_setkeys(coll_t cid
, const ghobject_t
&oid
,
60 const map
<string
, bufferlist
> &attrset
) {
62 uint64_t start_time
= Cycles::rdtsc();
63 t
.omap_setkeys(cid
, oid
, attrset
);
64 omap_setkeys_ticks
.add(Cycles::rdtsc() - start_time
);
66 void omap_rmkeys(coll_t cid
, const ghobject_t
&oid
,
67 const set
<string
> &keys
) {
68 uint64_t start_time
= Cycles::rdtsc();
69 t
.omap_rmkeys(cid
, oid
, keys
);
70 omap_rmkeys_ticks
.add(Cycles::rdtsc() - start_time
);
73 void apply_encode_decode() {
75 ObjectStore::Transaction d
;
76 uint64_t start_time
= Cycles::rdtsc();
78 encode_ticks
.add(Cycles::rdtsc() - start_time
);
80 bufferlist::iterator bliter
= bl
.begin();
81 start_time
= Cycles::rdtsc();
83 decode_ticks
.add(Cycles::rdtsc() - start_time
);
86 void apply_iterate() {
87 uint64_t start_time
= Cycles::rdtsc();
88 ObjectStore::Transaction::iterator i
= t
.begin();
90 ObjectStore::Transaction::Op
*op
= i
.decode_op();
93 case ObjectStore::Transaction::OP_WRITE
:
95 ghobject_t oid
= i
.get_oid(op
->oid
);
100 case ObjectStore::Transaction::OP_SETATTR
:
102 ghobject_t oid
= i
.get_oid(op
->oid
);
103 string name
= i
.decode_string();
106 map
<string
, bufferptr
> to_set
;
107 to_set
[name
] = bufferptr(bl
.c_str(), bl
.length());
110 case ObjectStore::Transaction::OP_OMAP_SETKEYS
:
112 ghobject_t oid
= i
.get_oid(op
->oid
);
113 map
<string
, bufferptr
> aset
;
114 i
.decode_attrset(aset
);
117 case ObjectStore::Transaction::OP_OMAP_RMKEYS
:
119 ghobject_t oid
= i
.get_oid(op
->oid
);
121 i
.decode_keyset(keys
);
126 iterate_ticks
.add(Cycles::rdtsc() - start_time
);
129 static void dump_stat() {
130 cerr
<< " write op: " << Cycles::to_microseconds(write_ticks
.ticks
) << "us count: " << write_ticks
.count
<< std::endl
;
131 cerr
<< " setattr op: " << Cycles::to_microseconds(setattr_ticks
.ticks
) << "us count: " << setattr_ticks
.count
<< std::endl
;
132 cerr
<< " omap_setkeys op: " << Cycles::to_microseconds(Transaction::omap_setkeys_ticks
.ticks
) << "us count: " << Transaction::omap_setkeys_ticks
.count
<< std::endl
;
133 cerr
<< " omap_rmkeys op: " << Cycles::to_microseconds(Transaction::omap_rmkeys_ticks
.ticks
) << "us count: " << Transaction::omap_rmkeys_ticks
.count
<< std::endl
;
134 cerr
<< " encode op: " << Cycles::to_microseconds(Transaction::encode_ticks
.ticks
) << "us count: " << Transaction::encode_ticks
.count
<< std::endl
;
135 cerr
<< " decode op: " << Cycles::to_microseconds(Transaction::decode_ticks
.ticks
) << "us count: " << Transaction::decode_ticks
.count
<< std::endl
;
136 cerr
<< " iterate op: " << Cycles::to_microseconds(Transaction::iterate_ticks
.ticks
) << "us count: " << Transaction::iterate_ticks
.count
<< std::endl
;
141 static const uint64_t Kib
= 1024;
142 static const uint64_t Mib
= 1024 * 1024;
143 static const string info_epoch_attr
;
144 static const string info_info_attr
;
145 static const string attr
;
146 static const string snapset_attr
;
147 static const string pglog_attr
;
148 static const coll_t meta_cid
;
149 static const coll_t cid
;
150 static const ghobject_t pglog_oid
;
151 static const ghobject_t info_oid
;
152 map
<string
, bufferlist
> data
;
154 ghobject_t
create_object() {
155 bufferlist bl
= generate_random(100, 1);
156 return ghobject_t(hobject_t(string("obj_")+string(bl
.c_str()), string(), rand() & 2 ? CEPH_NOSNAP
: rand(), rand() & 0xFF, 0, ""));
160 bufferlist
generate_random(uint64_t len
, int frag
) {
161 static const char alphanum
[] = "0123456789"
162 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
163 "abcdefghijklmnopqrstuvwxyz";
164 uint64_t per_frag
= len
/ frag
;
166 for (int i
= 0; i
< frag
; i
++ ) {
167 bufferptr
bp(per_frag
);
168 for (unsigned int j
= 0; j
< len
; j
++) {
169 bp
[j
] = alphanum
[rand() % (sizeof(alphanum
) - 1)];
177 uint64_t four_kb
= Kib
* 4;
178 uint64_t one_mb
= Mib
* 1;
179 uint64_t four_mb
= Mib
* 4;
180 data
["4k"] = generate_random(four_kb
, 1);
181 data
["1m"] = generate_random(one_mb
, 1);
182 data
["4m"] = generate_random(four_mb
, 1);
183 data
[attr
] = generate_random(256, 1);
184 data
[snapset_attr
] = generate_random(32, 1);
185 data
[pglog_attr
] = generate_random(128, 1);
186 data
[info_epoch_attr
] = generate_random(4, 1);
187 data
[info_info_attr
] = generate_random(560, 1);
190 uint64_t rados_write_4k(int times
) {
192 uint64_t len
= Kib
*4;
193 for (int i
= 0; i
< times
; i
++) {
194 uint64_t start_time
= 0;
197 ghobject_t oid
= create_object();
198 start_time
= Cycles::rdtsc();
199 t
.write(cid
, oid
, 0, len
, data
["4k"]);
200 t
.setattr(cid
, oid
, attr
, data
[attr
]);
201 t
.setattr(cid
, oid
, snapset_attr
, data
[snapset_attr
]);
202 t
.apply_encode_decode();
204 ticks
+= Cycles::rdtsc() - start_time
;
208 map
<string
, bufferlist
> pglog_attrset
;
209 map
<string
, bufferlist
> info_attrset
;
211 keys
.insert(pglog_attr
);
212 pglog_attrset
[pglog_attr
] = data
[pglog_attr
];
213 info_attrset
[info_epoch_attr
] = data
[info_epoch_attr
];
214 info_attrset
[info_info_attr
] = data
[info_info_attr
];
215 start_time
= Cycles::rdtsc();
216 t
.omap_setkeys(meta_cid
, pglog_oid
, pglog_attrset
);
217 t
.omap_setkeys(meta_cid
, info_oid
, info_attrset
);
218 t
.omap_rmkeys(meta_cid
, pglog_oid
, keys
);
219 t
.apply_encode_decode();
221 ticks
+= Cycles::rdtsc() - start_time
;
227 const string
PerfCase::info_epoch_attr("11.40_epoch");
228 const string
PerfCase::info_info_attr("11.40_info");
229 const string
PerfCase::attr("_");
230 const string
PerfCase::snapset_attr("snapset");
231 const string
PerfCase::pglog_attr("pglog_attr");
232 const coll_t
PerfCase::meta_cid
;
233 const coll_t
PerfCase::cid
;
234 const ghobject_t
PerfCase::pglog_oid(hobject_t(sobject_t(object_t("cid_pglog"), 0)));
235 const ghobject_t
PerfCase::info_oid(hobject_t(sobject_t(object_t("infos"), 0)));
236 Transaction::Tick
Transaction::write_ticks
, Transaction::setattr_ticks
, Transaction::omap_setkeys_ticks
, Transaction::omap_rmkeys_ticks
;
237 Transaction::Tick
Transaction::encode_ticks
, Transaction::decode_ticks
, Transaction::iterate_ticks
;
239 void usage(const string
&name
) {
240 cerr
<< "Usage: " << name
<< " [times] "
244 int main(int argc
, char **argv
)
246 vector
<const char*> args
;
247 argv_to_vec(argc
, (const char **)argv
, args
);
249 auto cct
= global_init(NULL
, args
, CEPH_ENTITY_TYPE_CLIENT
,
250 CODE_ENVIRONMENT_UTILITY
, 0);
251 common_init_finish(g_ceph_context
);
252 g_ceph_context
->_conf
->apply_changes(NULL
);
255 cerr
<< "args: " << args
<< std::endl
;
256 if (args
.size() < 1) {
261 uint64_t times
= atoi(args
[0]);
263 uint64_t ticks
= c
.rados_write_4k(times
);
264 Transaction::dump_stat();
265 cerr
<< " Total rados op " << times
<< " run time " << Cycles::to_microseconds(ticks
) << "us." << std::endl
;