From 5dd9b2ae1fd3fcea48c10609b24c960333c35b2c Mon Sep 17 00:00:00 2001 From: Haomai Wang Date: Sat, 7 Jun 2014 18:57:29 +0800 Subject: [PATCH] Make KeyValueStore support set_alloc_hint op Add a new config let KeyValueStore support configurable strip size. set_alloc_hint op can affect the strip size of the specified object and the expect write size will become the strip size of the object. Signed-off-by: Haomai Wang --- src/common/config_opts.h | 1 + src/os/KeyValueStore.cc | 55 +++++++++++++++++++++++++++++++++++++--- src/os/KeyValueStore.h | 10 +++++--- 3 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/common/config_opts.h b/src/common/config_opts.h index d2d884d434bd0..18b0a2ab44747 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -692,6 +692,7 @@ OPTION(keyvaluestore_debug_check_backend, OPT_BOOL, 0) // Expensive debugging ch OPTION(keyvaluestore_op_threads, OPT_INT, 2) OPTION(keyvaluestore_op_thread_timeout, OPT_INT, 60) OPTION(keyvaluestore_op_thread_suicide_timeout, OPT_INT, 180) +OPTION(keyvaluestore_default_strip_size, OPT_INT, 4096) // Only affect new object // max bytes to search ahead in journal searching for corruption OPTION(journal_max_corrupt_search, OPT_U64, 10<<20) diff --git a/src/os/KeyValueStore.cc b/src/os/KeyValueStore.cc index 08af6391196d0..b20f9cae472ed 100644 --- a/src/os/KeyValueStore.cc +++ b/src/os/KeyValueStore.cc @@ -509,6 +509,7 @@ KeyValueStore::KeyValueStore(const std::string &base, perf_logger(NULL), m_keyvaluestore_queue_max_ops(g_conf->keyvaluestore_queue_max_ops), m_keyvaluestore_queue_max_bytes(g_conf->keyvaluestore_queue_max_bytes), + m_keyvaluestore_strip_size(g_conf->keyvaluestore_default_strip_size), do_update(do_update) { ostringstream oss; @@ -873,6 +874,7 @@ int KeyValueStore::mount() goto close_current_fd; } + default_strip_size = m_keyvaluestore_strip_size; backend.reset(dbomap); } @@ -1450,11 +1452,12 @@ unsigned KeyValueStore::_do_transaction(Transaction& transaction, case Transaction::OP_SETALLOCHINT: { - // TODO: can kvstore make use of the hint? coll_t cid(i.decode_cid()); ghobject_t oid = i.decode_oid(); - i.decode_length(); // uint64_t expected_object_size - i.decode_length(); // uint64_t expected_write_size + uint64_t expected_object_size = i.decode_length(); + uint64_t expected_write_size = i.decode_length(); + r = _set_alloc_hint(cid, oid, expected_object_size, + expected_write_size, t); } break; @@ -2974,11 +2977,53 @@ int KeyValueStore::_split_collection(coll_t cid, uint32_t bits, uint32_t rem, return 0; } +int KeyValueStore::_set_alloc_hint(coll_t cid, const ghobject_t& oid, + uint64_t expected_object_size, + uint64_t expected_write_size, + BufferTransaction &t) +{ + dout(15) << __func__ << " " << cid << "/" << oid << " object_size " + << expected_object_size << " write_size " + << expected_write_size << dendl; + + int r = 0; + StripObjectMap::StripObjectHeader *header; + + r = t.lookup_cached_header(cid, oid, &header, false); + if (r < 0) { + dout(10) << __func__ << " " << cid << "/" << oid + << " failed to get header: r = " << r << dendl; + return r; + } + + bool blank = true; + for (vector::iterator it = header->bits.begin(); + it != header->bits.end(); ++it) { + if (*it) { + blank = false; + break; + } + } + + // Now only consider to change "strip_size" when the object is blank, + // because set_alloc_hint is expected to be very lightweight + if (blank) { + header->strip_size = expected_write_size; + } + + dout(10) << __func__ << "" << cid << "/" << oid << " object_size " + << expected_object_size << " write_size " + << expected_write_size << " = " << r << dendl; + + return r; +} + const char** KeyValueStore::get_tracked_conf_keys() const { static const char* KEYS[] = { "keyvaluestore_queue_max_ops", "keyvaluestore_queue_max_bytes", + "keyvaluestore_strip_size", NULL }; return KEYS; @@ -2992,6 +3037,10 @@ void KeyValueStore::handle_conf_change(const struct md_config_t *conf, m_keyvaluestore_queue_max_ops = conf->keyvaluestore_queue_max_ops; m_keyvaluestore_queue_max_bytes = conf->keyvaluestore_queue_max_bytes; } + if (changed.count("keyvaluestore_default_strip_size")) { + m_keyvaluestore_strip_size = conf->keyvaluestore_default_strip_size; + default_strip_size = m_keyvaluestore_strip_size; + } } void KeyValueStore::dump_transactions(list& ls, uint64_t seq, OpSequencer *osr) diff --git a/src/os/KeyValueStore.h b/src/os/KeyValueStore.h index 02574596954a7..27eb993cbe7ac 100644 --- a/src/os/KeyValueStore.h +++ b/src/os/KeyValueStore.h @@ -48,6 +48,8 @@ enum kvstore_types { }; +static uint64_t default_strip_size = 1024; + class StripObjectMap: public GenericObjectMap { public: @@ -139,8 +141,6 @@ class StripObjectMap: public GenericObjectMap { ); StripObjectMap(KeyValueDB *db): GenericObjectMap(db) {} - - static const uint64_t default_strip_size = 1024; }; @@ -478,7 +478,10 @@ class KeyValueStore : public ObjectStore, const ghobject_t& newoid, uint64_t srcoff, uint64_t len, uint64_t dstoff, BufferTransaction &t); int _remove(coll_t cid, const ghobject_t& oid, BufferTransaction &t); - + int _set_alloc_hint(coll_t cid, const ghobject_t& oid, + uint64_t expected_object_size, + uint64_t expected_write_size, + BufferTransaction &t); void start_sync() {} void sync() {} @@ -582,6 +585,7 @@ class KeyValueStore : public ObjectStore, std::string m_osd_rollback_to_cluster_snap; int m_keyvaluestore_queue_max_ops; int m_keyvaluestore_queue_max_bytes; + int m_keyvaluestore_strip_size; int do_update; -- 2.39.5