[#2127] services/tree: Randomize node order for synchronization

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2022-12-10 13:50:08 +03:00 committed by Anton Nikiforov
parent 21c58c92a9
commit 387d1e2977
2 changed files with 22 additions and 2 deletions

View file

@ -22,6 +22,7 @@ Changelog for NeoFS Node
- Allow object removal without linking object (#2100)
- `neofs-cli container delete` command pre-checks container ownership (#2106)
- Policer cache size is now 1024 (#2158)
- Tree service now synchronizes with container nodes in a random order (#2127)
### Fixed
- Open FSTree in sync mode by default (#1992)

View file

@ -6,8 +6,10 @@ import (
"errors"
"fmt"
"io"
"math/rand"
"github.com/TrueCloudLab/frostfs-node/pkg/local_object_storage/pilorama"
"github.com/TrueCloudLab/frostfs-node/pkg/morph/client/netmap"
"github.com/TrueCloudLab/frostfs-node/pkg/network"
cid "github.com/TrueCloudLab/frostfs-sdk-go/container/id"
netmapSDK "github.com/TrueCloudLab/frostfs-sdk-go/netmap"
@ -39,7 +41,7 @@ func (s *Service) SynchronizeAllTrees(ctx context.Context, cid cid.ID) error {
d.Position = pos
d.Size = len(nodes)
nodes = append(nodes[:pos], nodes[pos+1:]...) // exclude that node
nodes = randomizeNodeOrder(nodes, pos)
if len(nodes) == 0 {
return errNoOtherNodes
}
@ -108,7 +110,7 @@ func (s *Service) SynchronizeTree(ctx context.Context, cid cid.ID, treeID string
d.Position = pos
d.Size = len(nodes)
nodes = append(nodes[:pos], nodes[pos+1:]...) // exclude that node
nodes = randomizeNodeOrder(nodes, pos)
if len(nodes) == 0 {
return errNoOtherNodes
}
@ -310,3 +312,20 @@ func (s *Service) syncLoop(ctx context.Context) {
}
}
}
// randomizeNodeOrder shuffles nodes and removes not a `pos` index.
// It is assumed that 0 <= pos < len(nodes)
func randomizeNodeOrder(cnrNodes []netmap.NodeInfo, pos int) []netmap.NodeInfo {
if len(cnrNodes) == 1 {
return nil
}
nodes := make([]netmap.NodeInfo, len(cnrNodes)-1)
n := copy(nodes, cnrNodes[:pos])
copy(nodes[n:], cnrNodes[pos+1:])
rand.Shuffle(len(nodes), func(i, j int) {
nodes[i], nodes[j] = nodes[j], nodes[i]
})
return nodes
}