forked from TrueCloudLab/frostfs-node
[#136] cmd/neofs-node: Use new metabase in app
Remove BoltDB bucket package. Construct meta.DB instance in node app. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
c0aa892161
commit
8125b544b4
4 changed files with 24 additions and 216 deletions
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/ecdsa"
|
"crypto/ecdsa"
|
||||||
"net"
|
"net"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -16,8 +17,8 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/core/container"
|
"github.com/nspcc-dev/neofs-node/pkg/core/container"
|
||||||
netmapCore "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
|
netmapCore "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket/boltdb"
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket/fsbucket"
|
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket/fsbucket"
|
||||||
|
meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
"github.com/nspcc-dev/neofs-node/pkg/morph/client"
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper"
|
"github.com/nspcc-dev/neofs-node/pkg/morph/client/container/wrapper"
|
||||||
nmwrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
|
nmwrapper "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
|
||||||
|
@ -29,6 +30,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/util/profiler"
|
"github.com/nspcc-dev/neofs-node/pkg/util/profiler"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
"go.etcd.io/bbolt"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"google.golang.org/grpc"
|
"google.golang.org/grpc"
|
||||||
)
|
)
|
||||||
|
@ -75,7 +77,9 @@ const (
|
||||||
cfgContainerFee = "container.fee"
|
cfgContainerFee = "container.fee"
|
||||||
|
|
||||||
cfgObjectStorage = "storage.object"
|
cfgObjectStorage = "storage.object"
|
||||||
cfgMetaStorage = "storage.meta"
|
|
||||||
|
cfgMetaBasePath = "storage.metabase.path"
|
||||||
|
cfgMetaBasePerm = "storage.metabase.perm"
|
||||||
|
|
||||||
cfgGCQueueSize = "gc.queuesize"
|
cfgGCQueueSize = "gc.queuesize"
|
||||||
cfgGCQueueTick = "gc.duration.sleep"
|
cfgGCQueueTick = "gc.duration.sleep"
|
||||||
|
@ -193,7 +197,7 @@ type cfgObject struct {
|
||||||
|
|
||||||
cnrStorage container.Source
|
cnrStorage container.Source
|
||||||
|
|
||||||
metastorage bucket.Bucket
|
metastorage *meta.DB
|
||||||
|
|
||||||
blobstorage bucket.Bucket
|
blobstorage bucket.Bucket
|
||||||
|
|
||||||
|
@ -319,7 +323,9 @@ func defaultConfiguration(v *viper.Viper) {
|
||||||
v.SetDefault(cfgNetmapFee, "1")
|
v.SetDefault(cfgNetmapFee, "1")
|
||||||
|
|
||||||
v.SetDefault(cfgObjectStorage+".type", "inmemory")
|
v.SetDefault(cfgObjectStorage+".type", "inmemory")
|
||||||
v.SetDefault(cfgMetaStorage+".type", "inmemory")
|
|
||||||
|
v.SetDefault(cfgMetaBasePath, "metabase")
|
||||||
|
v.SetDefault(cfgMetaBasePerm, 0600)
|
||||||
|
|
||||||
v.SetDefault(cfgLogLevel, "info")
|
v.SetDefault(cfgLogLevel, "info")
|
||||||
v.SetDefault(cfgLogFormat, "console")
|
v.SetDefault(cfgLogFormat, "console")
|
||||||
|
@ -355,8 +361,14 @@ func initLocalStorage(c *cfg) {
|
||||||
c.cfgObject.blobstorage, err = initBucket(cfgObjectStorage, c)
|
c.cfgObject.blobstorage, err = initBucket(cfgObjectStorage, c)
|
||||||
fatalOnErr(err)
|
fatalOnErr(err)
|
||||||
|
|
||||||
c.cfgObject.metastorage, err = initBucket(cfgMetaStorage, c)
|
boltDB, err := bbolt.Open(
|
||||||
|
c.viper.GetString(cfgMetaBasePath),
|
||||||
|
os.FileMode(c.viper.GetUint32(cfgMetaBasePerm)),
|
||||||
|
nil,
|
||||||
|
)
|
||||||
fatalOnErr(err)
|
fatalOnErr(err)
|
||||||
|
|
||||||
|
c.cfgObject.metastorage = meta.NewDB(boltDB)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initBucket(prefix string, c *cfg) (bucket bucket.Bucket, err error) {
|
func initBucket(prefix string, c *cfg) (bucket bucket.Bucket, err error) {
|
||||||
|
@ -366,16 +378,6 @@ func initBucket(prefix string, c *cfg) (bucket bucket.Bucket, err error) {
|
||||||
case inmemory:
|
case inmemory:
|
||||||
bucket = newBucket()
|
bucket = newBucket()
|
||||||
c.log.Info("using in-memory bucket", zap.String("storage", prefix))
|
c.log.Info("using in-memory bucket", zap.String("storage", prefix))
|
||||||
case boltdb.Name:
|
|
||||||
opts, err := boltdb.NewOptions(prefix, c.viper)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "can't create boltdb opts")
|
|
||||||
}
|
|
||||||
bucket, err = boltdb.NewBucket(&opts)
|
|
||||||
if err != nil {
|
|
||||||
return nil, errors.Wrap(err, "can't create boltdb bucket")
|
|
||||||
}
|
|
||||||
c.log.Info("using boltdb bucket", zap.String("storage", prefix))
|
|
||||||
case fsbucket.Name:
|
case fsbucket.Name:
|
||||||
bucket, err = fsbucket.NewBucket(prefix, c.viper)
|
bucket, err = fsbucket.NewBucket(prefix, c.viper)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/util/grace"
|
"github.com/nspcc-dev/neofs-node/pkg/util/grace"
|
||||||
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
func fatalOnErr(err error) {
|
func fatalOnErr(err error) {
|
||||||
|
@ -57,6 +58,12 @@ func wait(c *cfg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func shutdown(c *cfg) {
|
func shutdown(c *cfg) {
|
||||||
|
if err := c.cfgObject.metastorage.Close(); err != nil {
|
||||||
|
c.log.Error("could not close metabase",
|
||||||
|
zap.String("error", err.Error()),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
c.cfgGRPC.server.GracefulStop()
|
c.cfgGRPC.server.GracefulStop()
|
||||||
|
|
||||||
c.log.Info("gRPC server stopped")
|
c.log.Info("gRPC server stopped")
|
||||||
|
|
|
@ -1,107 +0,0 @@
|
||||||
package boltdb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
"go.etcd.io/bbolt"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
boltBucket struct {
|
|
||||||
db *bbolt.DB
|
|
||||||
name []byte
|
|
||||||
}
|
|
||||||
|
|
||||||
// Options groups the BoltDB bucket's options.
|
|
||||||
Options struct {
|
|
||||||
bbolt.Options
|
|
||||||
Name []byte
|
|
||||||
Path string
|
|
||||||
Perm os.FileMode
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
const defaultFilePermission = 0777
|
|
||||||
|
|
||||||
var errEmptyPath = errors.New("database empty path")
|
|
||||||
|
|
||||||
const Name = "boltdb"
|
|
||||||
|
|
||||||
func makeCopy(val []byte) []byte {
|
|
||||||
tmp := make([]byte, len(val))
|
|
||||||
copy(tmp, val)
|
|
||||||
|
|
||||||
return tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewOptions prepares options for badger instance.
|
|
||||||
func NewOptions(prefix string, v *viper.Viper) (opts Options, err error) {
|
|
||||||
prefix = prefix + "." + Name
|
|
||||||
|
|
||||||
opts = Options{
|
|
||||||
Options: bbolt.Options{
|
|
||||||
// set defaults:
|
|
||||||
Timeout: bbolt.DefaultOptions.Timeout,
|
|
||||||
FreelistType: bbolt.DefaultOptions.FreelistType,
|
|
||||||
|
|
||||||
// set config options:
|
|
||||||
NoSync: v.GetBool(prefix + ".no_sync"),
|
|
||||||
ReadOnly: v.GetBool(prefix + ".read_only"),
|
|
||||||
NoGrowSync: v.GetBool(prefix + ".no_grow_sync"),
|
|
||||||
NoFreelistSync: v.GetBool(prefix + ".no_freelist_sync"),
|
|
||||||
|
|
||||||
PageSize: v.GetInt(prefix + ".page_size"),
|
|
||||||
MmapFlags: v.GetInt(prefix + ".mmap_flags"),
|
|
||||||
InitialMmapSize: v.GetInt(prefix + ".initial_mmap_size"),
|
|
||||||
},
|
|
||||||
|
|
||||||
Name: []byte(Name),
|
|
||||||
Perm: defaultFilePermission,
|
|
||||||
Path: v.GetString(prefix + ".path"),
|
|
||||||
}
|
|
||||||
|
|
||||||
if opts.Path == "" {
|
|
||||||
return opts, errEmptyPath
|
|
||||||
}
|
|
||||||
|
|
||||||
if tmp := v.GetDuration(prefix + ".lock_timeout"); tmp > 0 {
|
|
||||||
opts.Timeout = tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
if perm := v.GetUint32(prefix + ".perm"); perm != 0 {
|
|
||||||
opts.Perm = os.FileMode(perm)
|
|
||||||
}
|
|
||||||
|
|
||||||
base := path.Dir(opts.Path)
|
|
||||||
if err := os.MkdirAll(base, opts.Perm); err != nil {
|
|
||||||
return opts, errors.Wrapf(err, "could not use `%s` dir", base)
|
|
||||||
}
|
|
||||||
|
|
||||||
return opts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewBucket creates badger-bucket instance.
|
|
||||||
func NewBucket(opts *Options) (bucket.Bucket, error) {
|
|
||||||
log.SetOutput(ioutil.Discard) // disable default logger
|
|
||||||
|
|
||||||
db, err := bbolt.Open(opts.Path, opts.Perm, &opts.Options)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = db.Update(func(tx *bbolt.Tx) error {
|
|
||||||
_, err := tx.CreateBucketIfNotExists(opts.Name)
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &boltBucket{db: db, name: opts.Name}, nil
|
|
||||||
}
|
|
|
@ -1,94 +0,0 @@
|
||||||
package boltdb
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/mr-tron/base58"
|
|
||||||
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/bucket"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"go.etcd.io/bbolt"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Get value by key or return error.
|
|
||||||
func (b *boltBucket) Get(key []byte) (data []byte, err error) {
|
|
||||||
err = b.db.View(func(txn *bbolt.Tx) error {
|
|
||||||
txn.Bucket(b.name).Cursor().Seek(key)
|
|
||||||
val := txn.Bucket(b.name).Get(key)
|
|
||||||
if val == nil {
|
|
||||||
return errors.Wrapf(bucket.ErrNotFound, "key=%s", base58.Encode(key))
|
|
||||||
}
|
|
||||||
|
|
||||||
data = makeCopy(val)
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set value for key.
|
|
||||||
func (b *boltBucket) Set(key, value []byte) error {
|
|
||||||
return b.db.Update(func(txn *bbolt.Tx) error {
|
|
||||||
k, v := makeCopy(key), makeCopy(value)
|
|
||||||
return txn.Bucket(b.name).Put(k, v)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Del removes item from bucket by key.
|
|
||||||
func (b *boltBucket) Del(key []byte) error {
|
|
||||||
return b.db.Update(func(txn *bbolt.Tx) error {
|
|
||||||
return txn.Bucket(b.name).Delete(key)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Has checks key exists.
|
|
||||||
func (b *boltBucket) Has(key []byte) bool {
|
|
||||||
_, err := b.Get(key)
|
|
||||||
return !errors.Is(errors.Cause(err), bucket.ErrNotFound)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Size returns size of database.
|
|
||||||
func (b *boltBucket) Size() int64 {
|
|
||||||
info, err := os.Stat(b.db.Path())
|
|
||||||
if err != nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
return info.Size()
|
|
||||||
}
|
|
||||||
|
|
||||||
// List all items in bucket.
|
|
||||||
func (b *boltBucket) List() ([][]byte, error) {
|
|
||||||
var items [][]byte
|
|
||||||
|
|
||||||
if err := b.db.View(func(txn *bbolt.Tx) error {
|
|
||||||
return txn.Bucket(b.name).ForEach(func(k, _ []byte) error {
|
|
||||||
items = append(items, makeCopy(k))
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return items, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter elements by filter closure.
|
|
||||||
func (b *boltBucket) Iterate(handler bucket.FilterHandler) error {
|
|
||||||
if handler == nil {
|
|
||||||
return bucket.ErrNilFilterHandler
|
|
||||||
}
|
|
||||||
|
|
||||||
return b.db.View(func(txn *bbolt.Tx) error {
|
|
||||||
return txn.Bucket(b.name).ForEach(func(k, v []byte) error {
|
|
||||||
if !handler(makeCopy(k), makeCopy(v)) {
|
|
||||||
return bucket.ErrIteratingAborted
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close bucket database.
|
|
||||||
func (b *boltBucket) Close() error {
|
|
||||||
return b.db.Close()
|
|
||||||
}
|
|
Loading…
Reference in a new issue