Bumped default db_mem to 2048, also enable WriteBufferManager costing to cache again

Also in this commit: Misc tweaks and fixups
This commit is contained in:
Calin Culianu 2025-09-17 11:28:05 -05:00
parent 96db8a3320
commit 84ff62f9ba
No known key found for this signature in database
GPG key ID: 21810A542031C02C
4 changed files with 23 additions and 21 deletions

View file

@ -692,7 +692,7 @@ rpcpassword = hunter1
# db_max_open_files = 1000
# Max RocksDB Memory in MiB - 'db_mem' - DEFAULT: 1024.0
# Max RocksDB Memory in MiB - 'db_mem' - DEFAULT: 2048.0
#
# Specifies roughly the maximum amount of memory to give to rocksdb. Larger
# values offer better performance, at the expense of memory consumption. Note
@ -705,7 +705,7 @@ rpcpassword = hunter1
# works well on an SSD. If using an HDD for the datadir, you may want to set
# this value higher than the default.
#
# db_mem = 1024.0
# db_mem = 2048.0
# RocksDB use "fsync" - 'db_use_fsync' - DEFAULT: false

View file

@ -599,8 +599,9 @@ void App::parseArgs()
"db_mem",
QString("Specify roughly the maximum amount of memory to give to rocksb. Larger values offer better performance,"
" at the expense of memory consumption. Specify a floating-point or integer value in MiB (1 MiB = 1048576 bytes)."
" Default is: %1.\n").arg(options->db.defaultMaxMem / 1024.0 / 1024.0, 0, 'f', 1),
QString("MB")
" Default is autodetection, which is either %1 or 25% of the total physical RAM in the system, whichever is smaller.\n")
.arg(options->db.autoDefaultMaxMem / 1024.0 / 1024.0, 0, 'f', 1),
QString("MiB")
},
{
"db-upgrade", "Enable " APPNAME " 1.x -> 2.x DB upgrade. Use this option the first time you install " APPNAME
@ -1302,8 +1303,8 @@ void App::parseArgs()
}
if (const bool pset = parser.isSet("db_mem"); pset || conf.hasValue("db_mem")) {
bool ok;
const double mb = pset ? parser.value("db_mem").toDouble(&ok) : conf.doubleValue("db_mem", options->db.defaultMaxMem, &ok);
if (const size_t bytes = mb*size_t(1024*1024); !ok || mb < 0. || !options->db.isMaxMemInBounds(bytes))
const double mb = pset ? parser.value("db_mem").toDouble(&ok) : conf.doubleValue("db_mem", options->db.autoDefaultMaxMem, &ok);
if (const size_t bytes = mb*size_t(1024ull*1024ull); !ok || mb < 0. || !options->db.isMaxMemInBounds(bytes))
throw BadArgs(QString("db_mem: bad value. Specify a value in the range [%1, %2]")
.arg(options->db.maxMemMin / 1024. / 1024., 0, 'f', 1).arg(options->db.maxMemMax / 1024. / 1024., 0, 'f', 1));
else {
@ -1312,12 +1313,12 @@ void App::parseArgs()
Util::AsyncOnObject(this, [mb]{ Debug() << "config: db_mem = " << mb; });
}
} else {
// User didn't specify db_mem, attempt to use default (1GiB), or 25% of total physical RAM, whichever is
// User didn't specify db_mem, attempt to use default (2GiB), or 25% of total physical RAM, whichever is
// smaller. Also apply a lower bound of 512MiB (which was the older Fulcrum default db_mem).
static_assert(Options::DBOpts::isMaxMemInBounds(Options::DBOpts::defaultMaxMem)
static_assert(Options::DBOpts::isMaxMemInBounds(Options::DBOpts::autoDefaultMaxMem)
&& Options::DBOpts::isMaxMemInBounds(Options::DBOpts::oldDefaultMaxMem));
const size_t memBytes = Util::getTotalPhysicalRAM() / 4u;
options->db.maxMem = std::max(std::min(options->db.defaultMaxMem, memBytes), options->db.oldDefaultMaxMem);
options->db.maxMem = std::max(std::min(options->db.autoDefaultMaxMem, memBytes), options->db.oldDefaultMaxMem);
}
if (conf.hasValue("db_use_fsync")) {
bool ok;

View file

@ -204,11 +204,12 @@ public:
unsigned keepLogFileNum = defaultKeepLogFileNum;
static constexpr bool isKeepLogFileNumInBounds(int64_t k) { return k >= int64_t(minKeepLogFileNum) && k <= int64_t(maxKeepLogFileNum); }
static constexpr size_t defaultMaxMem = 1024 * 1024 * 1024, // 1GiB
oldDefaultMaxMem = 512 * 1024 * 1024, // 512MiB; older Fulcrum default
maxMemMin = 50 * 1024 * 1024, // 50MiB
// db_mem defaults to autodetect mode, where we try to use max(oldDefaultMaxMem, min(autoDefaultMaxMem, 25% of totalPhysicalRam))
static constexpr size_t autoDefaultMaxMem = 2ull * 1024ull * 1024ull * 1024ull, // 2GiB
oldDefaultMaxMem = 512ull * 1024ull * 1024ull, // 512MiB; older Fulcrum default
maxMemMin = 50ull * 1024ull * 1024ull, // 50MiB
maxMemMax = std::numeric_limits<size_t>::max();
size_t maxMem = defaultMaxMem;
size_t maxMem = autoDefaultMaxMem;
static constexpr bool isMaxMemInBounds(size_t mem) { return mem >= maxMemMin && mem <= maxMemMax; }
/// db_use_fsync in conf file -- default false

View file

@ -1554,23 +1554,23 @@ void Storage::openOrCreateDB(bool bulkLoad)
if constexpr (TWO_LEVEL_INDEX)
SetupTwoLevelIndex(tableOptions);
// shared TableFactory for all column families
// Shared TableFactory for all column families
opts.table_factory.reset(rocksdb::NewBlockBasedTableFactory(tableOptions));
// setup shared write buffer manager (for memtables memory budgeting)
// - TODO right now we fix the cap of the write buffer manager's buffer size at db.maxMem / 2; tweak this.
auto writeBufferManager = std::make_shared<rocksdb::WriteBufferManager>(options->db.maxMem / 2/* Disabled to reduce lock contention: , tableOptions.block_cache*/ /* cost to block cache: hopefully this caps memory better? it appears to use locks though so many this will be slow?! TODO: experiment with and without this!! */);
// Setup shared write buffer manager (for memtables memory budgeting)
// - Note: we fix the cap of the write buffer manager's buffer size at db.maxMem / 2; Might need to tweak this, but works well so far.
auto writeBufferManager = std::make_shared<rocksdb::WriteBufferManager>(options->db.maxMem / 2, tableOptions.block_cache /* Cost to block cache: this caps memory better. It uses locks so it comes at expense of more lock contention. */);
p->db.writeBufferManager = writeBufferManager; // save shared_ptr to weak_ptr
opts.write_buffer_manager = writeBufferManager; // will be shared across all column families
// create the DB if it's not already present
// Create the DB if it's not already present
opts.create_if_missing = true;
opts.error_if_exists = false;
opts.compression = rocksdb::CompressionType::kNoCompression; // for now we go without compression. TODO: characterize what is fastest and best..
opts.compression = rocksdb::CompressionType::kNoCompression; // We find that the space savings of compression are not worth the tradeoff in terms of CPU load.
if (!bulkLoad) {
opts.max_open_files = options->db.maxOpenFiles <= 0 ? -1 : options->db.maxOpenFiles; ///< this affects memory usage see: https://github.com/facebook/rocksdb/issues/4112
opts.max_open_files = options->db.maxOpenFiles <= 0 ? -1 : options->db.maxOpenFiles; ///< This affects memory usage see: https://github.com/facebook/rocksdb/issues/4112
opts.keep_log_file_num = options->db.keepLogFileNum;
opts.use_fsync = options->db.useFsync; // the false default is perfectly safe, but Jt asked for this as an option, so here it is.
opts.use_fsync = options->db.useFsync; // The false default is perfectly safe, but Jt asked for this as an option, so here it is.
}
auto OptimizeForPointLookup = [this](rocksdb::ColumnFamilyOptions &cfopts) {