diff --git a/CHANGELOG.md b/CHANGELOG.md index bd6da79..d72d318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ - [#1](https://github.com/crypto-org-chain/cronos-store/pull/1) feature: add store, memiavl, versiondb. - [#3](https://github.com/crypto-org-chain/cronos-store/pull/3) feat(memiavl): MultiTree add chainId. - [#4](https://github.com/crypto-org-chain/cronos-store/pull/4) feat(versiondb/client): add dump versiondb changeset cmd. -- [#7](https://github.com/crypto-org-chain/cronos-store/pull/7) fix: memiavl WriteSnapshotWithContext cancel using wrong ctx. \ No newline at end of file +- [#7](https://github.com/crypto-org-chain/cronos-store/pull/7) fix: memiavl WriteSnapshotWithContext cancel using wrong ctx. +- [#19](https://github.com/crypto-org-chain/cronos-store/pull/19) feat(versiondb): make VersionDB configurable via VersionDBConfig and OpenVersionDBWithConfig. \ No newline at end of file diff --git a/versiondb/tsrocksdb/opts.go b/versiondb/tsrocksdb/opts.go index 8218cd9..c1fd33f 100644 --- a/versiondb/tsrocksdb/opts.go +++ b/versiondb/tsrocksdb/opts.go @@ -9,14 +9,34 @@ import ( const VersionDBCFName = "versiondb" +type VersionDBConfig struct { + CacheSizeMB int + BlockSizeKB int + CompressionThreads int + Parallelism int +} + +// DefaultVersionDBConfig sets the Default versiondb config +func DefaultVersionDBConfig() *VersionDBConfig { + return &VersionDBConfig{ + CacheSizeMB: 1024, + BlockSizeKB: 32, + CompressionThreads: 4, + Parallelism: runtime.NumCPU(), + } +} + // NewVersionDBOpts returns the options used for the versiondb column family. // FIXME: we don't enable dict compression for SSTFileWriter, because otherwise the file writer won't report correct file size. // https://github.com/facebook/rocksdb/issues/11146 -func NewVersionDBOpts(sstFileWriter bool) *grocksdb.Options { +func NewVersionDBOpts(cfg *VersionDBConfig, sstFileWriter bool) *grocksdb.Options { + if cfg == nil { + cfg = DefaultVersionDBConfig() + } opts := grocksdb.NewDefaultOptions() opts.SetCreateIfMissing(true) opts.SetComparator(CreateTSComparator()) - opts.IncreaseParallelism(runtime.NumCPU()) + opts.IncreaseParallelism(cfg.Parallelism) opts.OptimizeLevelStyleCompaction(512 * 1024 * 1024) opts.SetTargetFileSizeMultiplier(2) opts.SetLevelCompactionDynamicLevelBytes(true) @@ -24,16 +44,16 @@ func NewVersionDBOpts(sstFileWriter bool) *grocksdb.Options { // block based table options bbto := grocksdb.NewDefaultBlockBasedTableOptions() - // 1G block cache - bbto.SetBlockSize(32 * 1024) - bbto.SetBlockCache(grocksdb.NewLRUCache(1 << 30)) + // configurable via cfg.BlockSizeMB - in MB + bbto.SetBlockSize(cfg.BlockSizeKB * 1024) + bbto.SetBlockCache(grocksdb.NewLRUCache(uint64(cfg.CacheSizeMB) << 20)) bbto.SetFilterPolicy(grocksdb.NewRibbonHybridFilterPolicy(9.9, 1)) bbto.SetIndexType(grocksdb.KBinarySearchWithFirstKey) bbto.SetOptimizeFiltersForMemory(true) opts.SetBlockBasedTableFactory(bbto) // improve sst file creation speed: compaction or sst file writer. - opts.SetCompressionOptionsParallelThreads(4) + opts.SetCompressionOptionsParallelThreads(cfg.CompressionThreads) if !sstFileWriter { // compression options at bottommost level @@ -47,16 +67,18 @@ func NewVersionDBOpts(sstFileWriter bool) *grocksdb.Options { return opts } -// OpenVersionDB opens versiondb, the default column family is used for metadata, -// actually key-value pairs are stored on another column family named with "versiondb", +// OpenVersionDBWithConfig opens versiondb with custom configuration options. +// The default column family is used for metadata; +// actual key-value pairs are stored on another column family named with "versiondb", // which has user-defined timestamp enabled. -func OpenVersionDB(dir string) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, error) { +// This allows caller to customize configuration through VersionDBConfig. +func OpenVersionDBWithConfig(dir string, cfg *VersionDBConfig) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, error) { opts := grocksdb.NewDefaultOptions() opts.SetCreateIfMissing(true) opts.SetCreateIfMissingColumnFamilies(true) db, cfHandles, err := grocksdb.OpenDbColumnFamilies( opts, dir, []string{"default", VersionDBCFName}, - []*grocksdb.Options{opts, NewVersionDBOpts(false)}, + []*grocksdb.Options{opts, NewVersionDBOpts(cfg, false)}, ) if err != nil { return nil, nil, err @@ -64,12 +86,17 @@ func OpenVersionDB(dir string) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, erro return db, cfHandles[1], nil } +// OpenVersionDB opens versiondb using default configuration. +func OpenVersionDB(dir string) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, error) { + return OpenVersionDBWithConfig(dir, DefaultVersionDBConfig()) +} + // OpenVersionDBForReadOnly open versiondb in readonly mode -func OpenVersionDBForReadOnly(dir string, errorIfWalFileExists bool) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, error) { +func OpenVersionDBForReadOnly(dir string, cfg *VersionDBConfig, errorIfWalFileExists bool) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, error) { opts := grocksdb.NewDefaultOptions() db, cfHandles, err := grocksdb.OpenDbForReadOnlyColumnFamilies( opts, dir, []string{"default", VersionDBCFName}, - []*grocksdb.Options{opts, NewVersionDBOpts(false)}, + []*grocksdb.Options{opts, NewVersionDBOpts(cfg, false)}, errorIfWalFileExists, ) if err != nil { @@ -80,7 +107,7 @@ func OpenVersionDBForReadOnly(dir string, errorIfWalFileExists bool) (*grocksdb. // OpenVersionDBAndTrimHistory opens versiondb similar to `OpenVersionDB`, // but it also trim the versions newer than target one, can be used for rollback. -func OpenVersionDBAndTrimHistory(dir string, version int64) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, error) { +func OpenVersionDBAndTrimHistory(dir string, cfg *VersionDBConfig, version int64) (*grocksdb.DB, *grocksdb.ColumnFamilyHandle, error) { var ts [TimestampSize]byte binary.LittleEndian.PutUint64(ts[:], uint64(version)) @@ -89,7 +116,7 @@ func OpenVersionDBAndTrimHistory(dir string, version int64) (*grocksdb.DB, *groc opts.SetCreateIfMissingColumnFamilies(true) db, cfHandles, err := grocksdb.OpenDbAndTrimHistory( opts, dir, []string{"default", VersionDBCFName}, - []*grocksdb.Options{opts, NewVersionDBOpts(false)}, + []*grocksdb.Options{opts, NewVersionDBOpts(cfg, false)}, ts[:], ) if err != nil {