fix balance fallback replica placement (#8824)
This commit is contained in:
@@ -3,6 +3,8 @@ package balance
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/admin/topology"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage/super_block"
|
||||
"github.com/seaweedfs/seaweedfs/weed/worker/types"
|
||||
)
|
||||
@@ -125,3 +127,112 @@ func TestIsGoodMove_NilReplicaPlacement(t *testing.T) {
|
||||
t.Error("nil replica placement should allow any move")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCalculateBalanceScore_ReplicationAware(t *testing.T) {
|
||||
disk := func(dc, rack string) *topology.DiskInfo {
|
||||
return &topology.DiskInfo{
|
||||
DataCenter: dc,
|
||||
Rack: rack,
|
||||
DiskInfo: &master_pb.DiskInfo{MaxVolumeCount: 100, VolumeCount: 50},
|
||||
}
|
||||
}
|
||||
|
||||
// 001: same-rack replication — should prefer same rack and same DC
|
||||
rp001 := rp(t, "001")
|
||||
sameRack := calculateBalanceScore(disk("dc1", "r1"), "r1", "dc1", 0, rp001)
|
||||
diffRack := calculateBalanceScore(disk("dc1", "r2"), "r1", "dc1", 0, rp001)
|
||||
diffDC := calculateBalanceScore(disk("dc2", "r2"), "r1", "dc1", 0, rp001)
|
||||
if sameRack <= diffRack {
|
||||
t.Errorf("001: same-rack score (%v) should exceed different-rack score (%v)", sameRack, diffRack)
|
||||
}
|
||||
if sameRack <= diffDC {
|
||||
t.Errorf("001: same-rack score (%v) should exceed different-DC score (%v)", sameRack, diffDC)
|
||||
}
|
||||
|
||||
// 010: different-rack replication — should prefer different rack, same DC
|
||||
rp010 := rp(t, "010")
|
||||
sameRack = calculateBalanceScore(disk("dc1", "r1"), "r1", "dc1", 0, rp010)
|
||||
diffRack = calculateBalanceScore(disk("dc1", "r2"), "r1", "dc1", 0, rp010)
|
||||
if diffRack <= sameRack {
|
||||
t.Errorf("010: different-rack score (%v) should exceed same-rack score (%v)", diffRack, sameRack)
|
||||
}
|
||||
|
||||
// 100: different-DC replication — should prefer different DC
|
||||
rp100 := rp(t, "100")
|
||||
sameDC := calculateBalanceScore(disk("dc1", "r2"), "r1", "dc1", 0, rp100)
|
||||
diffDCScore := calculateBalanceScore(disk("dc2", "r2"), "r1", "dc1", 0, rp100)
|
||||
if diffDCScore <= sameDC {
|
||||
t.Errorf("100: different-DC score (%v) should exceed same-DC score (%v)", diffDCScore, sameDC)
|
||||
}
|
||||
|
||||
// nil rp: should prefer cross-rack/DC (default behavior)
|
||||
sameRack = calculateBalanceScore(disk("dc1", "r1"), "r1", "dc1", 0, nil)
|
||||
diffRack = calculateBalanceScore(disk("dc1", "r2"), "r1", "dc1", 0, nil)
|
||||
if diffRack <= sameRack {
|
||||
t.Errorf("nil rp: different-rack score (%v) should exceed same-rack score (%v)", diffRack, sameRack)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlanBalanceDestination_ChoosesBestValidCompositeDestination(t *testing.T) {
|
||||
servers := []serverSpec{
|
||||
{id: "node-a", diskType: "hdd", diskID: 1, dc: "dc1", rack: "rack1"},
|
||||
{id: "node-b", diskType: "hdd", diskID: 2, dc: "dc1", rack: "rack3"},
|
||||
{id: "node-c", diskType: "hdd", diskID: 3, dc: "dc1", rack: "rack1"},
|
||||
}
|
||||
volumes := makeVolumesWith("node-a", "hdd", "dc1", "rack1", "c1", 1, 1, withReplicas(11))
|
||||
replicas := []types.ReplicaLocation{
|
||||
loc("dc1", "rack1", "node-a"),
|
||||
loc("dc1", "rack1", "node-d"),
|
||||
loc("dc1", "rack2", "node-e"),
|
||||
}
|
||||
|
||||
plan, err := planBalanceDestination(buildTopology(servers, volumes), volumes[0], rp(t, "011"), replicas, map[string]int{
|
||||
"node-b": 0,
|
||||
"node-c": 0,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("planBalanceDestination failed: %v", err)
|
||||
}
|
||||
if plan.TargetNode != "node-c" {
|
||||
t.Fatalf("expected valid same-rack destination node-c, got %s", plan.TargetNode)
|
||||
}
|
||||
if plan.TargetRack != "rack1" {
|
||||
t.Fatalf("expected rack1 destination, got %s", plan.TargetRack)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateBalanceTask_FallbackSelectsValidCompositeDestination(t *testing.T) {
|
||||
servers := []serverSpec{
|
||||
{id: "node-a", diskType: "hdd", diskID: 1, dc: "dc1", rack: "rack1"},
|
||||
{id: "node-b", diskType: "hdd", diskID: 2, dc: "dc1", rack: "rack3"},
|
||||
{id: "node-c", diskType: "hdd", diskID: 3, dc: "dc1", rack: "rack1"},
|
||||
}
|
||||
volumes := makeVolumesWith("node-a", "hdd", "dc1", "rack1", "c1", 1, 1, withReplicas(11))
|
||||
clusterInfo := &types.ClusterInfo{
|
||||
ActiveTopology: buildTopology(servers, volumes),
|
||||
VolumeReplicaMap: map[uint32][]types.ReplicaLocation{
|
||||
1: {
|
||||
loc("dc1", "rack1", "node-a"),
|
||||
loc("dc1", "rack1", "node-d"),
|
||||
loc("dc1", "rack2", "node-e"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
task, destination := createBalanceTask("hdd", volumes[0], clusterInfo, "node-b", map[string]int{
|
||||
"node-b": 0,
|
||||
"node-c": 0,
|
||||
})
|
||||
if task == nil {
|
||||
t.Fatal("expected a balance task")
|
||||
}
|
||||
if destination != "node-c" {
|
||||
t.Fatalf("expected fallback destination node-c, got %s", destination)
|
||||
}
|
||||
if len(task.TypedParams.Targets) != 1 {
|
||||
t.Fatalf("expected 1 target, got %d", len(task.TypedParams.Targets))
|
||||
}
|
||||
if got := task.TypedParams.Targets[0].Node; got != "node-c:8080" {
|
||||
t.Fatalf("expected target node-c:8080, got %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user