diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 19f3082ec4b..3a9cfd70827 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -180,6 +180,12 @@ OPTION(mon_sync_debug_provider_fallback, OPT_STR, "") // monitor to be used as f OPTION(mon_sync_leader_kill_at, OPT_INT, 0) // kill the sync leader at a specifc point in the work flow OPTION(mon_sync_provider_kill_at, OPT_INT, 0) // kill the sync provider at a specific point in the work flow OPTION(mon_sync_requester_kill_at, OPT_INT, 0) // kill the sync requester at a specific point in the work flow +OPTION(mon_leveldb_write_buffer_size, OPT_U64, 32*1024*1024) // monitor's leveldb write buffer size +OPTION(mon_leveldb_cache_size, OPT_U64, 0) // monitor's leveldb cache size +OPTION(mon_leveldb_block_size, OPT_U64, 4*1024*1024) // monitor's leveldb block size +OPTION(mon_leveldb_bloom_size, OPT_INT, 0) // monitor's leveldb bloom bits per entry +OPTION(mon_leveldb_max_open_files, OPT_INT, 0) // monitor's leveldb max open files +OPTION(mon_leveldb_compression, OPT_BOOL, false) // monitor's leveldb uses compression OPTION(paxos_max_join_drift, OPT_INT, 10) // max paxos iterations before we must first sync the monitor stores OPTION(paxos_propose_interval, OPT_DOUBLE, 1.0) // gather updates for this long before proposing a map update OPTION(paxos_min_wait, OPT_DOUBLE, 0.05) // min time to gather updates for after period of inactivity @@ -429,6 +435,12 @@ OPTION(osd_op_history_duration, OPT_U32, 600) // Oldest completed op to track OPTION(osd_target_transaction_size, OPT_INT, 30) // to adjust various transactions that batch smaller items OPTION(osd_failsafe_full_ratio, OPT_FLOAT, .97) // what % full makes an OSD "full" (failsafe) OPTION(osd_failsafe_nearfull_ratio, OPT_FLOAT, .90) // what % full makes an OSD near full (failsafe) +OPTION(osd_leveldb_write_buffer_size, OPT_U64, 0) // OSD's leveldb write buffer size +OPTION(osd_leveldb_cache_size, OPT_U64, 0) // OSD's leveldb cache size +OPTION(osd_leveldb_block_size, OPT_U64, 0) // OSD's leveldb block size +OPTION(osd_leveldb_bloom_size, OPT_INT, 0) // OSD's leveldb bloom bits per entry +OPTION(osd_leveldb_max_open_files, OPT_INT, 0) // OSD's leveldb max open files +OPTION(osd_leveldb_compression, OPT_BOOL, true) // OSD's leveldb uses compression /** * osd_client_op_priority and osd_recovery_op_priority adjust the relative diff --git a/src/mon/MonitorDBStore.h b/src/mon/MonitorDBStore.h index 99c9b4fe9f5..ac2703ec5e6 100644 --- a/src/mon/MonitorDBStore.h +++ b/src/mon/MonitorDBStore.h @@ -474,6 +474,12 @@ class MonitorDBStore assert(0 != "MonitorDBStore: error initializing level db back storage"); } db.reset(db_ptr); + db->options.write_buffer_size = g_conf->mon_leveldb_write_buffer_size; + db->options.cache_size = g_conf->mon_leveldb_cache_size; + db->options.block_size = g_conf->mon_leveldb_block_size; + db->options.bloom_size = g_conf->mon_leveldb_bloom_size; + db->options.compression_enabled = g_conf->mon_leveldb_compression; + db->options.max_open_files = g_conf->mon_leveldb_max_open_files; } MonitorDBStore(LevelDBStore *db_ptr) { db.reset(db_ptr); diff --git a/src/os/FileStore.cc b/src/os/FileStore.cc index 9d393022f14..5170412183e 100644 --- a/src/os/FileStore.cc +++ b/src/os/FileStore.cc @@ -1647,6 +1647,14 @@ int FileStore::mount() { LevelDBStore *omap_store = new LevelDBStore(omap_dir); + + omap_store->options.write_buffer_size = g_conf->osd_leveldb_write_buffer_size; + omap_store->options.cache_size = g_conf->osd_leveldb_cache_size; + omap_store->options.block_size = g_conf->osd_leveldb_block_size; + omap_store->options.bloom_size = g_conf->osd_leveldb_bloom_size; + omap_store->options.compression_enabled = g_conf->osd_leveldb_compression; + omap_store->options.max_open_files = g_conf->osd_leveldb_max_open_files; + stringstream err; if (omap_store->create_and_open(err)) { delete omap_store; diff --git a/src/os/LevelDBStore.cc b/src/os/LevelDBStore.cc index 3d94096f93e..d7d125343a6 100644 --- a/src/os/LevelDBStore.cc +++ b/src/os/LevelDBStore.cc @@ -6,18 +6,42 @@ #include #include #include -#include "leveldb/db.h" -#include "leveldb/write_batch.h" -#include "leveldb/slice.h" #include using std::string; int LevelDBStore::init(ostream &out, bool create_if_missing) { - leveldb::Options options; - options.create_if_missing = create_if_missing; + leveldb::Options ldoptions; + + if (options.write_buffer_size) + ldoptions.write_buffer_size = options.write_buffer_size; + if (options.max_open_files) + ldoptions.max_open_files = options.max_open_files; + if (options.cache_size) { + leveldb::Cache *_db_cache = leveldb::NewLRUCache(options.cache_size); + db_cache.reset(_db_cache); + ldoptions.block_cache = db_cache.get(); + } + if (options.block_size) + ldoptions.block_size = options.block_size; + if (options.bloom_size) { + const leveldb::FilterPolicy *_filterpolicy = + leveldb::NewBloomFilterPolicy(options.bloom_size); + filterpolicy.reset(_filterpolicy); + ldoptions.filter_policy = filterpolicy.get(); + } + if (!options.compression_enabled) + ldoptions.compression = leveldb::kNoCompression; + if (options.block_restart_interval) + ldoptions.block_restart_interval = options.block_restart_interval; + + ldoptions.error_if_exists = options.error_if_exists; + ldoptions.paranoid_checks = options.paranoid_checks; + ldoptions.compression = leveldb::kNoCompression; + ldoptions.create_if_missing = create_if_missing; + leveldb::DB *_db; - leveldb::Status status = leveldb::DB::Open(options, path, &_db); + leveldb::Status status = leveldb::DB::Open(ldoptions, path, &_db); db.reset(_db); if (!status.ok()) { out << status.ToString() << std::endl; diff --git a/src/os/LevelDBStore.h b/src/os/LevelDBStore.h index 7f0e1542443..3d3b8e818f1 100644 --- a/src/os/LevelDBStore.h +++ b/src/os/LevelDBStore.h @@ -14,6 +14,8 @@ #include "leveldb/db.h" #include "leveldb/write_batch.h" #include "leveldb/slice.h" +#include "leveldb/cache.h" +#include "leveldb/filter_policy.h" /** * Uses LevelDB to implement the KeyValueDB interface @@ -21,11 +23,56 @@ class LevelDBStore : public KeyValueDB { string path; boost::scoped_ptr db; + boost::scoped_ptr db_cache; + boost::scoped_ptr filterpolicy; int init(ostream &out, bool create_if_missing); public: - LevelDBStore(const string &path) : path(path) {} + /** + * options_t: Holds options which are minimally interpreted + * on initialization and then passed through to LevelDB. + * We transform a couple of these into actual LevelDB + * structures, but the rest are simply passed through unchanged. See + * leveldb/options.h for more precise details on each. + * + * Set them after constructing the LevelDBStore, but before calling + * open() or create_and_open(). + */ + struct options_t { + uint64_t write_buffer_size; /// in-memory write buffer size + int max_open_files; /// maximum number of files LevelDB can open at once + uint64_t cache_size; /// size of extra decompressed cache to use + uint64_t block_size; /// user data per block + int bloom_size; /// number of bits per entry to put in a bloom filter + bool compression_enabled; /// whether to use libsnappy compression or not + + // don't change these ones. No, seriously + int block_restart_interval; + bool error_if_exists; + bool paranoid_checks; + + options_t() : + write_buffer_size(0), //< 0 means default + max_open_files(0), //< 0 means default + cache_size(0), //< 0 means no cache (default) + block_size(0), //< 0 means default + bloom_size(0), //< 0 means no bloom filter (default) + compression_enabled(true), //< set to false for no compression + block_restart_interval(0), //< 0 means default + error_if_exists(false), //< set to true if you want to check nonexistence + paranoid_checks(false) //< set to true if you want paranoid checks + {} + } options; + + LevelDBStore(const string &path) : + path(path), + db_cache(NULL), + filterpolicy(NULL), + options() + {} + + ~LevelDBStore() {} /// Opens underlying db int open(ostream &out) {