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 (
|
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) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue