From 7913681297b1b986b47366387e844955fac6063b Mon Sep 17 00:00:00 2001 From: Lisandro Pin Date: Wed, 29 Jan 2025 17:50:19 +0100 Subject: [PATCH] `ec.encode`: Display a warning on EC balancing if no replica placement settings are found. (#6487) --- weed/shell/command_ec_common.go | 28 +++++++++++------- weed/storage/super_block/replica_placement.go | 4 +++ .../super_block/replica_placement_test.go | 29 +++++++++++++++++++ 3 files changed, 51 insertions(+), 10 deletions(-) diff --git a/weed/shell/command_ec_common.go b/weed/shell/command_ec_common.go index 0e9062d23..afbb750aa 100644 --- a/weed/shell/command_ec_common.go +++ b/weed/shell/command_ec_common.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/rand/v2" + "slices" "sort" "sync" "time" @@ -19,7 +20,6 @@ import ( "github.com/seaweedfs/seaweedfs/weed/storage/super_block" "github.com/seaweedfs/seaweedfs/weed/storage/types" "google.golang.org/grpc" - "slices" ) type DataCenterId string @@ -176,20 +176,28 @@ func _getDefaultReplicaPlacement(commandEnv *CommandEnv) (*super_block.ReplicaPl } func parseReplicaPlacementArg(commandEnv *CommandEnv, replicaStr string) (*super_block.ReplicaPlacement, error) { + var rp *super_block.ReplicaPlacement + var err error + if replicaStr != "" { - rp, err := super_block.NewReplicaPlacementFromString(replicaStr) - if err == nil { - fmt.Printf("using replica placement %q for EC volumes\n", rp.String()) + rp, err = super_block.NewReplicaPlacementFromString(replicaStr) + if err != nil { + return rp, err } - return rp, err + fmt.Printf("using replica placement %q for EC volumes\n", rp.String()) + } else { + // No replica placement argument provided, resolve from master default settings. + rp, err = getDefaultReplicaPlacement(commandEnv) + if err != nil { + return rp, err + } + fmt.Printf("using master default replica placement %q for EC volumes\n", rp.String()) } - // No replica placement argument provided, resolve from master default settings. - rp, err := getDefaultReplicaPlacement(commandEnv) - if err == nil { - fmt.Printf("using master default replica placement %q for EC volumes\n", rp.String()) + if !rp.HasReplication() { + fmt.Printf("WARNING: replica placement type %q is empty!", rp.String()) } - return rp, err + return rp, nil } func collectTopologyInfo(commandEnv *CommandEnv, delayBeforeCollecting time.Duration) (topoInfo *master_pb.TopologyInfo, volumeSizeLimitMb uint64, err error) { diff --git a/weed/storage/super_block/replica_placement.go b/weed/storage/super_block/replica_placement.go index f6d14e25b..8ec44d48c 100644 --- a/weed/storage/super_block/replica_placement.go +++ b/weed/storage/super_block/replica_placement.go @@ -45,6 +45,10 @@ func NewReplicaPlacementFromByte(b byte) (*ReplicaPlacement, error) { return NewReplicaPlacementFromString(fmt.Sprintf("%03d", b)) } +func (rp *ReplicaPlacement) HasReplication() bool { + return rp.DiffDataCenterCount != 0 || rp.DiffRackCount != 0 || rp.SameRackCount != 0 +} + func (a *ReplicaPlacement) Equals(b *ReplicaPlacement) bool { if a == nil || b == nil { return false diff --git a/weed/storage/super_block/replica_placement_test.go b/weed/storage/super_block/replica_placement_test.go index 7742ba548..203e3e860 100644 --- a/weed/storage/super_block/replica_placement_test.go +++ b/weed/storage/super_block/replica_placement_test.go @@ -12,3 +12,32 @@ func TestReplicaPlacementSerialDeserial(t *testing.T) { t.Fail() } } + +func TestReplicaPlacementHasReplication(t *testing.T) { + testCases := []struct { + name string + replicaPlacement string + want bool + }{ + {"empty replica placement", "", false}, + {"no replication", "000", false}, + {"same rack replication", "100", true}, + {"diff rack replication", "020", true}, + {"DC replication", "003", true}, + {"full replication", "155", true}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rp, err := NewReplicaPlacementFromString(tc.replicaPlacement) + if err != nil { + t.Errorf("failed to initialize ReplicaPlacement: %v", err) + return + } + + if got, want := rp.HasReplication(), tc.want; got != want { + t.Errorf("expected %v, got %v", want, got) + } + }) + } +}