diff --git a/CHANGELOG.md b/CHANGELOG.md index 20d7618c008..d1c4e910ead 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,10 @@ a created Peapod file named `peapod.db` in the directory where the tree is located. For example, `/neofs/data/blobovcniza/*` -> `/neofs/data/peapod.db`. Notice that existing Blobovnicza trees are untouched. +To store small objects in more effective and simple sub-storage Peapod, replace +`blobovnicza` sub-storage with the `peapod` one. If storage node already stores +some data, don't forget to make data migration described above. + ## [0.37.0] - 2023-06-15 - Sogado ### Added diff --git a/cmd/neofs-node/config.go b/cmd/neofs-node/config.go index 5644ef7b205..3d419ead7f1 100644 --- a/cmd/neofs-node/config.go +++ b/cmd/neofs-node/config.go @@ -36,6 +36,7 @@ import ( "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/blobovniczatree" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/peapod" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine" meta "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/metabase" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/pilorama" @@ -264,6 +265,7 @@ func (a *applicationConfiguration) readConfig(c *config.Config) error { sub := fstreeconfig.From((*config.Config)(storagesCfg[i])) sCfg.depth = sub.Depth() sCfg.noSync = sub.NoSync() + case peapod.Type: default: return fmt.Errorf("invalid storage type: %s", storagesCfg[i].Type()) } @@ -732,6 +734,13 @@ func (c *cfg) shardOpts() []shardOptsWithID { return true }, }) + case peapod.Type: + ss = append(ss, blobstor.SubStorage{ + Storage: peapod.New(sRead.path, sRead.perm), + Policy: func(_ *objectSDK.Object, data []byte) bool { + return uint64(len(data)) < shCfg.smallSizeObjectLimit + }, + }) default: // should never happen, that has already // been handled: when the config was read diff --git a/cmd/neofs-node/config/engine/config_test.go b/cmd/neofs-node/config/engine/config_test.go index c57017fb586..40804583707 100644 --- a/cmd/neofs-node/config/engine/config_test.go +++ b/cmd/neofs-node/config/engine/config_test.go @@ -12,6 +12,7 @@ import ( fstreeconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/engine/shard/blobstor/fstree" piloramaconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/engine/shard/pilorama" configtest "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/test" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/peapod" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/shard/mode" "github.com/stretchr/testify/require" ) @@ -133,12 +134,9 @@ func TestEngineSection(t *testing.T) { require.Equal(t, 2, len(ss)) - blz := blobovniczaconfig.From((*config.Config)(ss[0])) - require.Equal(t, "tmp/1/blob/blobovnicza", ss[0].Path()) - require.EqualValues(t, 4194304, blz.Size()) - require.EqualValues(t, 1, blz.ShallowDepth()) - require.EqualValues(t, 4, blz.ShallowWidth()) - require.EqualValues(t, 50, blz.OpenedCacheSize()) + require.Equal(t, "tmp/1/blob/peapod.db", ss[0].Path()) + require.EqualValues(t, 0644, ss[0].Perm()) + require.EqualValues(t, peapod.Type, ss[0].Type()) require.Equal(t, "tmp/1/blob", ss[1].Path()) require.EqualValues(t, 0644, ss[1].Perm()) diff --git a/cmd/neofs-node/config/engine/shard/blobstor/config.go b/cmd/neofs-node/config/engine/shard/blobstor/config.go index 4e6dc86c2cb..fe9ccdc8cc0 100644 --- a/cmd/neofs-node/config/engine/shard/blobstor/config.go +++ b/cmd/neofs-node/config/engine/shard/blobstor/config.go @@ -7,6 +7,7 @@ import ( "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/engine/shard/blobstor/storage" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/blobovniczatree" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/peapod" ) // Config is a wrapper over the config section @@ -28,7 +29,7 @@ func (x *Config) Storages() []*storage.Config { switch typ { case "": return ss - case fstree.Type, blobovniczatree.Type: + case fstree.Type, blobovniczatree.Type, peapod.Type: sub := storage.From((*config.Config)(x).Sub(strconv.Itoa(i))) ss = append(ss, sub) default: diff --git a/cmd/neofs-node/validate.go b/cmd/neofs-node/validate.go index 5f337731d86..573e8acf584 100644 --- a/cmd/neofs-node/validate.go +++ b/cmd/neofs-node/validate.go @@ -11,6 +11,7 @@ import ( treeconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/tree" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/blobovniczatree" "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/fstree" + "github.com/nspcc-dev/neofs-node/pkg/local_object_storage/blobstor/peapod" "go.uber.org/zap/zapcore" ) @@ -54,7 +55,7 @@ func validateConfig(c *config.Config) error { } for i := range blobstor { switch blobstor[i].Type() { - case fstree.Type, blobovniczatree.Type: + case fstree.Type, blobovniczatree.Type, peapod.Type: default: // FIXME #1764 (@fyrchik): this line is currently unreachable, // because we panic in `sc.BlobStor().Storages()`. diff --git a/config/example/node.env b/config/example/node.env index 2e817505308..f9e1d49f84d 100644 --- a/config/example/node.env +++ b/config/example/node.env @@ -152,12 +152,9 @@ NEOFS_STORAGE_SHARD_1_METABASE_MAX_BATCH_DELAY=20ms NEOFS_STORAGE_SHARD_1_COMPRESS=false NEOFS_STORAGE_SHARD_1_SMALL_OBJECT_SIZE=102400 ### Blobovnicza config -NEOFS_STORAGE_SHARD_1_BLOBSTOR_0_TYPE=blobovnicza -NEOFS_STORAGE_SHARD_1_BLOBSTOR_0_PATH=tmp/1/blob/blobovnicza -NEOFS_STORAGE_SHARD_1_BLOBSTOR_0_SIZE=4194304 -NEOFS_STORAGE_SHARD_1_BLOBSTOR_0_DEPTH=1 -NEOFS_STORAGE_SHARD_1_BLOBSTOR_0_WIDTH=4 -NEOFS_STORAGE_SHARD_1_BLOBSTOR_0_OPENED_CACHE_CAPACITY=50 +NEOFS_STORAGE_SHARD_1_BLOBSTOR_0_TYPE=peapod +NEOFS_STORAGE_SHARD_1_BLOBSTOR_0_PATH=tmp/1/blob/peapod.db +NEOFS_STORAGE_SHARD_1_BLOBSTOR_0_PERM=0644 ### FSTree config NEOFS_STORAGE_SHARD_1_BLOBSTOR_1_TYPE=fstree NEOFS_STORAGE_SHARD_1_BLOBSTOR_1_PATH=tmp/1/blob diff --git a/config/example/node.json b/config/example/node.json index 908662ba1ac..1e33668c907 100644 --- a/config/example/node.json +++ b/config/example/node.json @@ -198,8 +198,8 @@ "small_object_size": 102400, "blobstor": [ { - "type": "blobovnicza", - "path": "tmp/1/blob/blobovnicza", + "type": "peapod", + "path": "tmp/1/blob/peapod.db", "perm": "0644", "size": 4194304, "depth": 1, diff --git a/config/example/node.yaml b/config/example/node.yaml index cfd3a6a9568..f0823a172db 100644 --- a/config/example/node.yaml +++ b/config/example/node.yaml @@ -194,8 +194,8 @@ storage: path: tmp/1/meta # metabase path blobstor: - - type: blobovnicza - path: tmp/1/blob/blobovnicza + - type: peapod + path: tmp/1/blob/peapod.db # path to Peapod database - type: fstree path: tmp/1/blob # blobstor path no_sync: true diff --git a/docs/storage-node-configuration.md b/docs/storage-node-configuration.md index 3ba935a3f37..ec30143bb06 100644 --- a/docs/storage-node-configuration.md +++ b/docs/storage-node-configuration.md @@ -175,7 +175,7 @@ The following table describes configuration for each shard. ### `blobstor` subsection Contains a list of substorages each with it's own type. -Currently only 2 types are supported: `fstree` and `blobovnicza`. +Currently only 3 types are supported: `fstree`, `blobovnicza` and `peapod`. ```yaml blobstor: @@ -215,6 +215,12 @@ blobstor: | `width` | `int` | `16` | Blobovnicza tree width. | | `opened_cache_capacity` | `int` | `16` | Maximum number of simultaneously opened blobovniczas. | +#### `peapod` type options +| Parameter | Type | Default value | Description | +|---------------------|-----------|---------------|-------------------------------------------------------| +| `path` | `string` | | Path to the Peapod database file. | +| `perm` | file mode | `0660` | Default permission for created files and directories. | + ### `gc` subsection Contains garbage-collection service configuration. It iterates over the blobstor and removes object the node no longer needs.