fix shell volume.balance bug (#4447)

This commit is contained in:
themarkchen 2023-05-04 22:35:37 +08:00 committed by GitHub
parent 6fdff0bb18
commit 7592d013fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 93 additions and 24 deletions

View file

@ -3,14 +3,15 @@ package shell
import ( import (
"flag" "flag"
"fmt" "fmt"
"io"
"os"
"time"
"github.com/seaweedfs/seaweedfs/weed/pb" "github.com/seaweedfs/seaweedfs/weed/pb"
"github.com/seaweedfs/seaweedfs/weed/storage/erasure_coding" "github.com/seaweedfs/seaweedfs/weed/storage/erasure_coding"
"github.com/seaweedfs/seaweedfs/weed/storage/super_block" "github.com/seaweedfs/seaweedfs/weed/storage/super_block"
"github.com/seaweedfs/seaweedfs/weed/storage/types" "github.com/seaweedfs/seaweedfs/weed/storage/types"
"golang.org/x/exp/slices" "golang.org/x/exp/slices"
"io"
"os"
"time"
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb" "github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
"github.com/seaweedfs/seaweedfs/weed/storage/needle" "github.com/seaweedfs/seaweedfs/weed/storage/needle"
@ -371,33 +372,24 @@ func isGoodMove(placement *super_block.ReplicaPlacement, existingReplicas []*Vol
return false return false
} }
} }
dcs, racks := make(map[string]bool), make(map[string]int)
// existing replicas except the one on sourceNode
existingReplicasExceptSourceNode := make([]*VolumeReplica, 0)
for _, replica := range existingReplicas { for _, replica := range existingReplicas {
if replica.location.dataNode.Id != sourceNode.info.Id { if replica.location.dataNode.Id != sourceNode.info.Id {
dcs[replica.location.DataCenter()] = true existingReplicasExceptSourceNode = append(existingReplicasExceptSourceNode, replica)
racks[replica.location.Rack()]++
} }
} }
dcs[targetNode.dc] = true // target location
racks[fmt.Sprintf("%s %s", targetNode.dc, targetNode.rack)]++ targetLocation := location{
dc: targetNode.dc,
if len(dcs) != placement.DiffDataCenterCount+1 { rack: targetNode.rack,
return false dataNode: targetNode.info,
} }
if len(racks) != placement.DiffRackCount+placement.DiffDataCenterCount+1 { // check if this satisfies replication requirements
return false return satisfyReplicaPlacement(placement, existingReplicasExceptSourceNode, targetLocation)
}
for _, sameRackCount := range racks {
if sameRackCount != placement.SameRackCount+1 {
return false
}
}
return true
} }
func adjustAfterMove(v *master_pb.VolumeInformationMessage, volumeReplicas map[uint32][]*VolumeReplica, fullNode *Node, emptyNode *Node) { func adjustAfterMove(v *master_pb.VolumeInformationMessage, volumeReplicas map[uint32][]*VolumeReplica, fullNode *Node, emptyNode *Node) {

View file

@ -1,9 +1,10 @@
package shell package shell
import ( import (
"testing"
"github.com/seaweedfs/seaweedfs/weed/storage/types" "github.com/seaweedfs/seaweedfs/weed/storage/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"testing"
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb" "github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
"github.com/seaweedfs/seaweedfs/weed/storage/super_block" "github.com/seaweedfs/seaweedfs/weed/storage/super_block"
@ -149,6 +150,82 @@ func TestIsGoodMove(t *testing.T) {
targetLocation: location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn3"}}, targetLocation: location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn3"}},
expected: true, expected: true,
}, },
{
name: "test 011 switch which rack has more replicas",
replication: "011",
replicas: []*VolumeReplica{
{
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
},
{
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn2"}},
},
{
location: &location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn3"}},
},
},
sourceLocation: location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
targetLocation: location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn4"}},
expected: true,
},
{
name: "test 011 move the lonely replica to another racks",
replication: "011",
replicas: []*VolumeReplica{
{
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
},
{
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn2"}},
},
{
location: &location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn3"}},
},
},
sourceLocation: location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn3"}},
targetLocation: location{"dc1", "r3", &master_pb.DataNodeInfo{Id: "dn4"}},
expected: true,
},
{
name: "test 011 move to wrong racks",
replication: "011",
replicas: []*VolumeReplica{
{
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
},
{
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn2"}},
},
{
location: &location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn3"}},
},
},
sourceLocation: location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
targetLocation: location{"dc1", "r3", &master_pb.DataNodeInfo{Id: "dn4"}},
expected: false,
},
{
name: "test 011 move all to the same rack",
replication: "011",
replicas: []*VolumeReplica{
{
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn1"}},
},
{
location: &location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn2"}},
},
{
location: &location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn3"}},
},
},
sourceLocation: location{"dc1", "r2", &master_pb.DataNodeInfo{Id: "dn3"}},
targetLocation: location{"dc1", "r1", &master_pb.DataNodeInfo{Id: "dn4"}},
expected: false,
},
} }
for _, tt := range tests { for _, tt := range tests {