Merge pull request #1351 from ceph/wip-7248

osd: OSD: limit the value of 'size' and 'count' on 'osd bench'

Reviewed-by: Sage Weil <sage@inktank.com>
This commit is contained in:
Sage Weil 2014-03-05 14:18:28 -08:00
commit b093958a11
3 changed files with 99 additions and 0 deletions

View File

@ -439,6 +439,8 @@ ceph osd pool get rbd crush_ruleset | grep 'crush_ruleset: 0'
ceph osd thrash 10
set +e
# expect error about missing 'pool' argument
@ -460,4 +462,43 @@ ceph heap dump
ceph heap stop_profiler
ceph heap release
# test osd bench limits
# As we should not rely on defaults (as they may change over time),
# lets inject some values and perform some simple tests
# max iops: 10 # 100 IOPS
# max throughput: 10485760 # 10MB/s
# max block size: 2097152 # 2MB
# duration: 10 # 10 seconds
ceph tell osd.0 injectargs "\
--osd-bench-duration 10 \
--osd-bench-max-block-size 2097152 \
--osd-bench-large-size-max-throughput 10485760 \
--osd-bench-small-size-max-iops 10"
# anything with a bs larger than 2097152 must fail
expect_false ceph tell osd.0 bench 1 2097153
# but using 'osd_bench_max_bs' must succeed
ceph tell osd.0 bench 1 2097152
# we assume 1MB as a large bs; anything lower is a small bs
# for a 4096 bytes bs, for 10 seconds, we are limited by IOPS
# max count: 409600
# more than max count must not be allowed
expect_false ceph tell osd.0 bench 409601 4096
# but 409600 must be succeed
ceph tell osd.0 bench 409600 4096
# for a large bs, we are limited by throughput.
# for a 2MB block size for 10 seconds, out max count is 50
# max count: 50
# more than max count must not be allowed
expect_false ceph tell osd.0 bench 51 2097152
# but 50 must succeed
ceph tell osd.0 bench 50 2097152
echo OK

View File

@ -580,6 +580,11 @@ OPTION(osd_objectstore, OPT_STR, "filestore") // ObjectStore backend type
// Set to true for testing. Users should NOT set this.
OPTION(osd_debug_override_acting_compat, OPT_BOOL, false)
OPTION(osd_bench_small_size_max_iops, OPT_U32, 100) // 100 IOPS
OPTION(osd_bench_large_size_max_throughput, OPT_U64, 100 << 20) // 100 MB/s
OPTION(osd_bench_max_block_size, OPT_U64, 64 << 20) // cap the block size at 64MB
OPTION(osd_bench_duration, OPT_U32, 30) // duration of 'osd bench', capped at 30s to avoid triggering timeouts
OPTION(filestore_debug_disable_sharded_check, OPT_BOOL, false)
/// filestore wb throttle limits

View File

@ -4283,6 +4283,59 @@ void OSD::do_command(Connection *con, tid_t tid, vector<string>& cmd, bufferlist
cmd_getval(cct, cmdmap, "count", count, (int64_t)1 << 30);
cmd_getval(cct, cmdmap, "size", bsize, (int64_t)4 << 20);
uint32_t duration = g_conf->osd_bench_duration;
if (bsize > (int64_t) g_conf->osd_bench_max_block_size) {
// let us limit the block size because the next checks rely on it
// having a sane value. If we allow any block size to be set things
// can still go sideways.
ss << "block 'size' values are capped at "
<< prettybyte_t(g_conf->osd_bench_max_block_size) << ". If you wish to use"
<< " a higher value, please adjust 'osd_bench_max_block_size'";
r = -EINVAL;
goto out;
} else if (bsize < (int64_t) (1 << 20)) {
// entering the realm of small block sizes.
// limit the count to a sane value, assuming a configurable amount of
// IOPS and duration, so that the OSD doesn't get hung up on this,
// preventing timeouts from going off
int64_t max_count =
bsize * duration * g_conf->osd_bench_small_size_max_iops;
if (count > max_count) {
ss << "'count' values greater than " << max_count
<< " for a block size of " << prettybyte_t(bsize) << ", assuming "
<< g_conf->osd_bench_small_size_max_iops << " IOPS,"
<< " for " << duration << " seconds,"
<< " can cause ill effects on osd. "
<< " Please adjust 'osd_bench_small_size_max_iops' with a higher"
<< " value if you wish to use a higher 'count'.";
r = -EINVAL;
goto out;
}
} else {
// 1MB block sizes are big enough so that we get more stuff done.
// However, to avoid the osd from getting hung on this and having
// timers being triggered, we are going to limit the count assuming
// a configurable throughput and duration.
int64_t total_throughput =
g_conf->osd_bench_large_size_max_throughput * duration;
int64_t max_count = (int64_t) (total_throughput / bsize);
if (count > max_count) {
ss << "'count' values greater than " << max_count
<< " for a block size of " << prettybyte_t(bsize) << ", assuming "
<< prettybyte_t(g_conf->osd_bench_large_size_max_throughput) << "/s,"
<< " for " << duration << " seconds,"
<< " can cause ill effects on osd. "
<< " Please adjust 'osd_bench_large_size_max_throughput'"
<< " with a higher value if you wish to use a higher 'count'.";
r = -EINVAL;
goto out;
}
}
dout(1) << " bench count " << count
<< " bsize " << prettybyte_t(bsize) << dendl;
bufferlist bl;
bufferptr bp(bsize);
bp.zero();