[#47] shard: Switch container size metric from physical to logical capacity
Signed-off-by: Artem Tataurov <a.tataurov@yadro.com>
This commit is contained in:
parent
901d62567d
commit
362f24953a
6 changed files with 78 additions and 8 deletions
|
@ -11,6 +11,7 @@ Changelog for FrostFS Node
|
||||||
- Add command `frostfs-adm morph netmap-candidates` (#1889)
|
- Add command `frostfs-adm morph netmap-candidates` (#1889)
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
- Change `frostfs_node_engine_container_size` to counting sizes of logical objects
|
||||||
- `common.PrintVerbose` prints via `cobra.Command.Printf` (#1962)
|
- `common.PrintVerbose` prints via `cobra.Command.Printf` (#1962)
|
||||||
- Env prefix in configuration changed to `FROSTFS_*` (#43)
|
- Env prefix in configuration changed to `FROSTFS_*` (#43)
|
||||||
- Link object is broadcast throughout the whole container now (#57)
|
- Link object is broadcast throughout the whole container now (#57)
|
||||||
|
|
|
@ -23,6 +23,7 @@ type DeleteRes struct {
|
||||||
rawRemoved uint64
|
rawRemoved uint64
|
||||||
availableRemoved uint64
|
availableRemoved uint64
|
||||||
sizes []uint64
|
sizes []uint64
|
||||||
|
availableSizes []uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
// AvailableObjectsRemoved returns the number of removed available
|
// AvailableObjectsRemoved returns the number of removed available
|
||||||
|
@ -36,11 +37,16 @@ func (d DeleteRes) RawObjectsRemoved() uint64 {
|
||||||
return d.rawRemoved
|
return d.rawRemoved
|
||||||
}
|
}
|
||||||
|
|
||||||
// RemovedObjectSizes returns the sizes of removed objects.
|
// RemovedPhysicalObjectSizes returns the sizes of removed physical objects.
|
||||||
func (d DeleteRes) RemovedObjectSizes() []uint64 {
|
func (d DeleteRes) RemovedPhysicalObjectSizes() []uint64 {
|
||||||
return d.sizes
|
return d.sizes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemovedLogicalObjectSizes returns the sizes of removed logical objects.
|
||||||
|
func (d DeleteRes) RemovedLogicalObjectSizes() []uint64 {
|
||||||
|
return d.availableSizes
|
||||||
|
}
|
||||||
|
|
||||||
// SetAddresses is a Delete option to set the addresses of the objects to delete.
|
// SetAddresses is a Delete option to set the addresses of the objects to delete.
|
||||||
//
|
//
|
||||||
// Option is required.
|
// Option is required.
|
||||||
|
@ -73,10 +79,11 @@ func (db *DB) Delete(prm DeletePrm) (DeleteRes, error) {
|
||||||
var availableRemoved uint64
|
var availableRemoved uint64
|
||||||
var err error
|
var err error
|
||||||
var sizes = make([]uint64, len(prm.addrs))
|
var sizes = make([]uint64, len(prm.addrs))
|
||||||
|
var availableSizes = make([]uint64, len(prm.addrs))
|
||||||
|
|
||||||
err = db.boltDB.Update(func(tx *bbolt.Tx) error {
|
err = db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||||
// We need to clear slice because tx can try to execute multiple times.
|
// We need to clear slice because tx can try to execute multiple times.
|
||||||
rawRemoved, availableRemoved, err = db.deleteGroup(tx, prm.addrs, sizes)
|
rawRemoved, availableRemoved, err = db.deleteGroup(tx, prm.addrs, sizes, availableSizes)
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -90,6 +97,7 @@ func (db *DB) Delete(prm DeletePrm) (DeleteRes, error) {
|
||||||
rawRemoved: rawRemoved,
|
rawRemoved: rawRemoved,
|
||||||
availableRemoved: availableRemoved,
|
availableRemoved: availableRemoved,
|
||||||
sizes: sizes,
|
sizes: sizes,
|
||||||
|
availableSizes: availableSizes,
|
||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +107,7 @@ func (db *DB) Delete(prm DeletePrm) (DeleteRes, error) {
|
||||||
// objects that were stored. The second return value is a logical objects
|
// objects that were stored. The second return value is a logical objects
|
||||||
// removed number: objects that were available (without Tombstones, GCMarks
|
// removed number: objects that were available (without Tombstones, GCMarks
|
||||||
// non-expired, etc.)
|
// non-expired, etc.)
|
||||||
func (db *DB) deleteGroup(tx *bbolt.Tx, addrs []oid.Address, sizes []uint64) (uint64, uint64, error) {
|
func (db *DB) deleteGroup(tx *bbolt.Tx, addrs []oid.Address, sizes []uint64, availableSizes []uint64) (uint64, uint64, error) {
|
||||||
refCounter := make(referenceCounter, len(addrs))
|
refCounter := make(referenceCounter, len(addrs))
|
||||||
currEpoch := db.epochState.CurrentEpoch()
|
currEpoch := db.epochState.CurrentEpoch()
|
||||||
|
|
||||||
|
@ -119,6 +127,7 @@ func (db *DB) deleteGroup(tx *bbolt.Tx, addrs []oid.Address, sizes []uint64) (ui
|
||||||
|
|
||||||
if available {
|
if available {
|
||||||
availableDeleted++
|
availableDeleted++
|
||||||
|
availableSizes[i] = size
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
"github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
apistatus "github.com/TrueCloudLab/frostfs-sdk-go/client/status"
|
apistatus "github.com/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||||
|
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
"github.com/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "github.com/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
|
@ -23,10 +24,17 @@ type InhumePrm struct {
|
||||||
forceRemoval bool
|
forceRemoval bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeletionInfo contains details on deleted object.
|
||||||
|
type DeletionInfo struct {
|
||||||
|
Size uint64
|
||||||
|
CID cid.ID
|
||||||
|
}
|
||||||
|
|
||||||
// InhumeRes encapsulates results of Inhume operation.
|
// InhumeRes encapsulates results of Inhume operation.
|
||||||
type InhumeRes struct {
|
type InhumeRes struct {
|
||||||
deletedLockObj []oid.Address
|
deletedLockObj []oid.Address
|
||||||
availableImhumed uint64
|
availableImhumed uint64
|
||||||
|
deletionDetails []DeletionInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// AvailableInhumed return number of available object
|
// AvailableInhumed return number of available object
|
||||||
|
@ -42,6 +50,27 @@ func (i InhumeRes) DeletedLockObjects() []oid.Address {
|
||||||
return i.deletedLockObj
|
return i.deletedLockObj
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDeletionInfoLength returns amount of stored elements
|
||||||
|
// in deleted sizes array.
|
||||||
|
func (i InhumeRes) GetDeletionInfoLength() int {
|
||||||
|
return len(i.deletionDetails)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetDeletionInfoByIndex returns both deleted object sizes and
|
||||||
|
// associated container ID by index.
|
||||||
|
func (i InhumeRes) GetDeletionInfoByIndex(target int) DeletionInfo {
|
||||||
|
return i.deletionDetails[target]
|
||||||
|
}
|
||||||
|
|
||||||
|
// StoreDeletionInfo stores size of deleted object and associated container ID
|
||||||
|
// in corresponding arrays.
|
||||||
|
func (i *InhumeRes) storeDeletionInfo(containerID cid.ID, deletedSize uint64) {
|
||||||
|
i.deletionDetails = append(i.deletionDetails, DeletionInfo{
|
||||||
|
Size: deletedSize,
|
||||||
|
CID: containerID,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// SetAddresses sets a list of object addresses that should be inhumed.
|
// SetAddresses sets a list of object addresses that should be inhumed.
|
||||||
func (p *InhumePrm) SetAddresses(addrs ...oid.Address) {
|
func (p *InhumePrm) SetAddresses(addrs ...oid.Address) {
|
||||||
p.target = addrs
|
p.target = addrs
|
||||||
|
@ -164,10 +193,10 @@ func (db *DB) Inhume(prm InhumePrm) (res InhumeRes, err error) {
|
||||||
obj, err := db.get(tx, prm.target[i], buf, false, true, currEpoch)
|
obj, err := db.get(tx, prm.target[i], buf, false, true, currEpoch)
|
||||||
targetKey := addressKey(prm.target[i], buf)
|
targetKey := addressKey(prm.target[i], buf)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
containerID, _ := obj.ContainerID()
|
||||||
if inGraveyardWithKey(targetKey, graveyardBKT, garbageBKT) == 0 {
|
if inGraveyardWithKey(targetKey, graveyardBKT, garbageBKT) == 0 {
|
||||||
// object is available, decrement the
|
|
||||||
// logical counter
|
|
||||||
inhumed++
|
inhumed++
|
||||||
|
res.storeDeletionInfo(containerID, obj.PayloadSize())
|
||||||
}
|
}
|
||||||
|
|
||||||
// if object is stored, and it is regular object then update bucket
|
// if object is stored, and it is regular object then update bucket
|
||||||
|
|
|
@ -83,9 +83,12 @@ func (s *Shard) delete(prm DeletePrm) (DeleteRes, error) {
|
||||||
s.decObjectCounterBy(physical, res.RawObjectsRemoved())
|
s.decObjectCounterBy(physical, res.RawObjectsRemoved())
|
||||||
s.decObjectCounterBy(logical, res.AvailableObjectsRemoved())
|
s.decObjectCounterBy(logical, res.AvailableObjectsRemoved())
|
||||||
for i := range prm.addr {
|
for i := range prm.addr {
|
||||||
removedPayload := res.RemovedObjectSizes()[i]
|
removedPayload := res.RemovedPhysicalObjectSizes()[i]
|
||||||
totalRemovedPayload += removedPayload
|
totalRemovedPayload += removedPayload
|
||||||
s.addToContainerSize(prm.addr[i].Container().EncodeToString(), -int64(removedPayload))
|
logicalRemovedPayload := res.RemovedLogicalObjectSizes()[i]
|
||||||
|
if logicalRemovedPayload > 0 {
|
||||||
|
s.addToContainerSize(prm.addr[i].Container().EncodeToString(), -int64(logicalRemovedPayload))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
s.addToPayloadSize(-int64(totalRemovedPayload))
|
s.addToPayloadSize(-int64(totalRemovedPayload))
|
||||||
|
|
||||||
|
|
|
@ -268,6 +268,13 @@ func (s *Shard) collectExpiredObjects(ctx context.Context, e Event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for i < res.GetDeletionInfoLength() {
|
||||||
|
delInfo := res.GetDeletionInfoByIndex(i)
|
||||||
|
s.addToContainerSize(delInfo.CID.EncodeToString(), -int64(delInfo.Size))
|
||||||
|
i++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Shard) collectExpiredTombstones(ctx context.Context, e Event) {
|
func (s *Shard) collectExpiredTombstones(ctx context.Context, e Event) {
|
||||||
|
@ -408,6 +415,13 @@ func (s *Shard) HandleExpiredTombstones(tss []meta.TombstonedObject) {
|
||||||
|
|
||||||
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for i < res.GetDeletionInfoLength() {
|
||||||
|
delInfo := res.GetDeletionInfoByIndex(i)
|
||||||
|
s.addToContainerSize(delInfo.CID.EncodeToString(), -int64(delInfo.Size))
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
// drop just processed expired tombstones
|
// drop just processed expired tombstones
|
||||||
// from graveyard
|
// from graveyard
|
||||||
err = s.metaBase.DropGraves(tss)
|
err = s.metaBase.DropGraves(tss)
|
||||||
|
@ -446,6 +460,13 @@ func (s *Shard) HandleExpiredLocks(lockers []oid.Address) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for i < res.GetDeletionInfoLength() {
|
||||||
|
delInfo := res.GetDeletionInfoByIndex(i)
|
||||||
|
s.addToContainerSize(delInfo.CID.EncodeToString(), -int64(delInfo.Size))
|
||||||
|
i++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HandleDeletedLocks unlocks all objects which were locked by lockers.
|
// HandleDeletedLocks unlocks all objects which were locked by lockers.
|
||||||
|
|
|
@ -111,6 +111,13 @@ func (s *Shard) Inhume(prm InhumePrm) (InhumeRes, error) {
|
||||||
|
|
||||||
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
s.decObjectCounterBy(logical, res.AvailableInhumed())
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
for i < res.GetDeletionInfoLength() {
|
||||||
|
delInfo := res.GetDeletionInfoByIndex(i)
|
||||||
|
s.addToContainerSize(delInfo.CID.EncodeToString(), -int64(delInfo.Size))
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
|
||||||
if deletedLockObjs := res.DeletedLockObjects(); len(deletedLockObjs) != 0 {
|
if deletedLockObjs := res.DeletedLockObjects(); len(deletedLockObjs) != 0 {
|
||||||
s.deletedLockCallBack(context.Background(), deletedLockObjs)
|
s.deletedLockCallBack(context.Background(), deletedLockObjs)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue