diff --git a/config/config.go b/config/config.go index 805200b09..5c9fed622 100644 --- a/config/config.go +++ b/config/config.go @@ -230,6 +230,8 @@ type DBConfig struct { SyncWrites bool `mapstructure:"sync_writes"` // InMemory sets the database to run in-memory, without touching the disk. InMemory bool `mapstructure:"in_memory"` + // if zero, default is used + BadgerCompactors int `mapstructure:"badger_num_compactors"` } func (dbc DBConfig) Validate() error { diff --git a/config/toml.go b/config/toml.go index 9ee3d544d..823f61290 100644 --- a/config/toml.go +++ b/config/toml.go @@ -150,6 +150,8 @@ sync_writes = {{ .DBConfig.SyncWrites }} # When true, the database will run in-memory only (FOR EXPERIMENTAL USE ONLY) in_memory = {{ .DBConfig.InMemory }} +# When zero/empty, uses default +badger_num_compactors = {{ .DBConfig.BadgerCompactors }} ####################################################### ### Instrumentation Configuration Options ### diff --git a/node/node.go b/node/node.go index f0f1a88e5..1a33d8323 100644 --- a/node/node.go +++ b/node/node.go @@ -108,7 +108,8 @@ func NewNode( dstore = datastore.NewMapDatastore() } else { // TODO(omritoptx): Move dymint to const - baseKV = store.NewKVStore(conf.RootDir, conf.DBPath, "dymint", conf.DBConfig.SyncWrites, logger) + baseKV = store.NewKVStore(conf.RootDir, conf.DBPath, "dymint", + store.BadgerOpts{SyncWrites: conf.DBConfig.SyncWrites, NumCompactors: conf.DBConfig.BadgerCompactors}, logger) path := filepath.Join(store.Rootify(conf.RootDir, conf.DBPath), "blocksync") var err error dstore, err = leveldb.NewDatastore(path, &leveldb.Options{}) diff --git a/store/badger.go b/store/badger.go index 5fbb244f5..8212b9d7e 100644 --- a/store/badger.go +++ b/store/badger.go @@ -43,9 +43,13 @@ func NewDefaultInMemoryKVStore() KV { } } -func NewKVStore(rootDir, dbPath, dbName string, syncWrites bool, logger types.Logger) KV { +func NewKVStore(rootDir, dbPath, dbName string, + badgerOpts BadgerOpts, + + logger types.Logger, +) KV { path := filepath.Join(Rootify(rootDir, dbPath), dbName) - opts := memoryEfficientBadgerConfig(path, syncWrites) + opts := memoryEfficientBadgerConfig(path, badgerOpts) db, err := badger.Open(*opts) if err != nil { panic(err) @@ -60,7 +64,7 @@ func NewKVStore(rootDir, dbPath, dbName string, syncWrites bool, logger types.Lo // NewDefaultKVStore creates instance of default key-value store. func NewDefaultKVStore(rootDir, dbPath, dbName string) KV { - return NewKVStore(rootDir, dbPath, dbName, true, log.NewNopLogger()) + return NewKVStore(rootDir, dbPath, dbName, BadgerOpts{SyncWrites: true}, log.NewNopLogger()) } // Rootify is helper function to make config creation independent of root dir @@ -228,13 +232,18 @@ func (i *BadgerIterator) Discard() { i.txn.Discard() } +type BadgerOpts struct { + SyncWrites bool + NumCompactors int +} + // memoryEfficientBadgerConfig sets badger configuration parameters to reduce memory usage, specially during compactions to avoid memory spikes that causes OOM. // based on https://github.com/celestiaorg/celestia-node/issues/2905 -func memoryEfficientBadgerConfig(path string, syncWrites bool) *badger.Options { +func memoryEfficientBadgerConfig(path string, o BadgerOpts) *badger.Options { opts := badger.DefaultOptions(path) // this must be copied // SyncWrites is a configuration option in Badger that determines whether writes are immediately synced to disk or no. // If set to true it writes to the write-ahead log (value log) are synced to disk before being applied to the LSM tree. - opts.SyncWrites = syncWrites + opts.SyncWrites = o.SyncWrites // default 64mib => 0 - disable block cache // BlockCacheSize specifies how much data cache should hold in memory. // It improves lookup performance but increases memory consumption. @@ -254,7 +263,10 @@ func memoryEfficientBadgerConfig(path string, syncWrites bool) *badger.Options { // default 15 => 5 - this prevents memory growth on CPU constraint systems by blocking all writers opts.NumLevelZeroTablesStall = 5 // reducing number compactors, makes it slower but reduces memory usage during compaction - opts.NumCompactors = 2 + opts.NumCompactors = o.NumCompactors + if opts.NumCompactors == 0 { + opts.NumCompactors = 2 // default + } // makes sure badger is always compacted on shutdown opts.CompactL0OnClose = true