mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
fix shell volume.balance bug (#4447)
This commit is contained in:
parent
6fdff0bb18
commit
7592d013fe
|
@ -3,14 +3,15 @@ package shell
|
|||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage/erasure_coding"
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage/super_block"
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage/types"
|
||||
"golang.org/x/exp/slices"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage/needle"
|
||||
|
@ -371,33 +372,24 @@ func isGoodMove(placement *super_block.ReplicaPlacement, existingReplicas []*Vol
|
|||
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 {
|
||||
if replica.location.dataNode.Id != sourceNode.info.Id {
|
||||
dcs[replica.location.DataCenter()] = true
|
||||
racks[replica.location.Rack()]++
|
||||
existingReplicasExceptSourceNode = append(existingReplicasExceptSourceNode, replica)
|
||||
}
|
||||
}
|
||||
|
||||
dcs[targetNode.dc] = true
|
||||
racks[fmt.Sprintf("%s %s", targetNode.dc, targetNode.rack)]++
|
||||
|
||||
if len(dcs) != placement.DiffDataCenterCount+1 {
|
||||
return false
|
||||
// target location
|
||||
targetLocation := location{
|
||||
dc: targetNode.dc,
|
||||
rack: targetNode.rack,
|
||||
dataNode: targetNode.info,
|
||||
}
|
||||
|
||||
if len(racks) != placement.DiffRackCount+placement.DiffDataCenterCount+1 {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, sameRackCount := range racks {
|
||||
if sameRackCount != placement.SameRackCount+1 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
// check if this satisfies replication requirements
|
||||
return satisfyReplicaPlacement(placement, existingReplicasExceptSourceNode, targetLocation)
|
||||
}
|
||||
|
||||
func adjustAfterMove(v *master_pb.VolumeInformationMessage, volumeReplicas map[uint32][]*VolumeReplica, fullNode *Node, emptyNode *Node) {
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
package shell
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage/types"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
|
||||
"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"}},
|
||||
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 {
|
||||
|
|
Loading…
Reference in a new issue