Browse Source

shell: ensure dc and rack does not change for replicated volumes

fix https://github.com/chrislusf/seaweedfs/issues/1203
pull/1206/head
Chris Lu 5 years ago
parent
commit
3a1d017de2
  1. 28
      weed/shell/command_volume_balance.go

28
weed/shell/command_volume_balance.go

@ -109,14 +109,7 @@ func (c *commandVolumeBalance) Do(args []string, commandEnv *CommandEnv, writer
return nil return nil
} }
func balanceVolumeServers(commandEnv *CommandEnv, dataNodeInfos []*master_pb.DataNodeInfo, volumeSizeLimit uint64, collection string, applyBalancing bool) error {
var nodes []*Node
for _, dn := range dataNodeInfos {
nodes = append(nodes, &Node{
info: dn,
})
}
func balanceVolumeServers(commandEnv *CommandEnv, nodes []*Node, volumeSizeLimit uint64, collection string, applyBalancing bool) error {
// balance writable volumes // balance writable volumes
for _, n := range nodes { for _, n := range nodes {
@ -151,15 +144,19 @@ func balanceVolumeServers(commandEnv *CommandEnv, dataNodeInfos []*master_pb.Dat
return nil return nil
} }
func collectVolumeServersByType(t *master_pb.TopologyInfo, selectedDataCenter string) (typeToNodes map[uint64][]*master_pb.DataNodeInfo) {
typeToNodes = make(map[uint64][]*master_pb.DataNodeInfo)
func collectVolumeServersByType(t *master_pb.TopologyInfo, selectedDataCenter string) (typeToNodes map[uint64][]*Node) {
typeToNodes = make(map[uint64][]*Node)
for _, dc := range t.DataCenterInfos { for _, dc := range t.DataCenterInfos {
if selectedDataCenter != "" && dc.Id != selectedDataCenter { if selectedDataCenter != "" && dc.Id != selectedDataCenter {
continue continue
} }
for _, r := range dc.RackInfos { for _, r := range dc.RackInfos {
for _, dn := range r.DataNodeInfos { for _, dn := range r.DataNodeInfos {
typeToNodes[dn.MaxVolumeCount] = append(typeToNodes[dn.MaxVolumeCount], dn)
typeToNodes[dn.MaxVolumeCount] = append(typeToNodes[dn.MaxVolumeCount], &Node{
info: dn,
dc: dc.Id,
rack: r.Id,
})
} }
} }
} }
@ -169,6 +166,8 @@ func collectVolumeServersByType(t *master_pb.TopologyInfo, selectedDataCenter st
type Node struct { type Node struct {
info *master_pb.DataNodeInfo info *master_pb.DataNodeInfo
selectedVolumes map[uint32]*master_pb.VolumeInformationMessage selectedVolumes map[uint32]*master_pb.VolumeInformationMessage
dc string
rack string
} }
func sortWritableVolumes(volumes []*master_pb.VolumeInformationMessage) { func sortWritableVolumes(volumes []*master_pb.VolumeInformationMessage) {
@ -210,6 +209,13 @@ func balanceSelectedVolume(commandEnv *CommandEnv, nodes []*Node, sortCandidates
sortCandidatesFn(candidateVolumes) sortCandidatesFn(candidateVolumes)
for _, v := range candidateVolumes { for _, v := range candidateVolumes {
if v.ReplicaPlacement > 0 {
if fullNode.dc != emptyNode.dc && fullNode.rack != emptyNode.rack {
// TODO this logic is too simple, but should work most of the time
// Need a correct algorithm to handle all different cases
continue
}
}
if _, found := emptyNode.selectedVolumes[v.Id]; !found { if _, found := emptyNode.selectedVolumes[v.Id]; !found {
if err := moveVolume(commandEnv, v, fullNode, emptyNode, applyBalancing); err == nil { if err := moveVolume(commandEnv, v, fullNode, emptyNode, applyBalancing); err == nil {
delete(fullNode.selectedVolumes, v.Id) delete(fullNode.selectedVolumes, v.Id)

Loading…
Cancel
Save