diff options
Diffstat (limited to 'weed/shell/command_volume_balance.go')
| -rw-r--r-- | weed/shell/command_volume_balance.go | 41 |
1 files changed, 33 insertions, 8 deletions
diff --git a/weed/shell/command_volume_balance.go b/weed/shell/command_volume_balance.go index 6ba376d2c..bc0adfc5f 100644 --- a/weed/shell/command_volume_balance.go +++ b/weed/shell/command_volume_balance.go @@ -64,7 +64,7 @@ func (c *commandVolumeBalance) Help() string { func (c *commandVolumeBalance) Do(args []string, commandEnv *CommandEnv, writer io.Writer) (err error) { balanceCommand := flag.NewFlagSet(c.Name(), flag.ContinueOnError) - collection := balanceCommand.String("collection", "EACH_COLLECTION", "collection name, or use \"ALL_COLLECTIONS\" across collections, \"EACH_COLLECTION\" for each collection") + collection := balanceCommand.String("collection", "ALL_COLLECTIONS", "collection name, or use \"ALL_COLLECTIONS\" across collections, \"EACH_COLLECTION\" for each collection") dc := balanceCommand.String("dataCenter", "", "only apply the balancing for this dataCenter") applyBalancing := balanceCommand.Bool("force", false, "apply the balancing plan.") if err = balanceCommand.Parse(args); err != nil { @@ -213,6 +213,18 @@ func (n *Node) localVolumeNextRatio(capacityFunc CapacityFunc) float64 { return divide(len(n.selectedVolumes)+1, capacityFunc(n.info)) } +func (n *Node) isOneVolumeOnly() bool { + if len(n.selectedVolumes) != 1 { + return false + } + for _, disk := range n.info.DiskInfos { + if disk.VolumeCount == 1 && disk.MaxVolumeCount == 1 { + return true + } + } + return false +} + func (n *Node) selectVolumes(fn func(v *master_pb.VolumeInformationMessage) bool) { n.selectedVolumes = make(map[uint32]*master_pb.VolumeInformationMessage) for _, diskInfo := range n.info.DiskInfos { @@ -230,12 +242,6 @@ func sortWritableVolumes(volumes []*master_pb.VolumeInformationMessage) { }) } -func sortReadOnlyVolumes(volumes []*master_pb.VolumeInformationMessage) { - slices.SortFunc(volumes, func(a, b *master_pb.VolumeInformationMessage) bool { - return a.Id < b.Id - }) -} - func balanceSelectedVolume(commandEnv *CommandEnv, diskType types.DiskType, volumeReplicas map[uint32][]*VolumeReplica, nodes []*Node, capacityFunc CapacityFunc, sortCandidatesFn func(volumes []*master_pb.VolumeInformationMessage), applyBalancing bool) (err error) { selectedVolumeCount, volumeMaxCount := 0, 0 var nodesWithCapacity []*Node @@ -263,7 +269,14 @@ func balanceSelectedVolume(commandEnv *CommandEnv, diskType types.DiskType, volu fmt.Printf("no volume server found with capacity for %s", diskType.ReadableString()) return nil } - fullNode := nodesWithCapacity[len(nodesWithCapacity)-1] + + var fullNode *Node + for fullNodeIndex := len(nodesWithCapacity) - 1; fullNodeIndex >= 0; fullNodeIndex-- { + fullNode = nodesWithCapacity[fullNodeIndex] + if !fullNode.isOneVolumeOnly() { + break + } + } var candidateVolumes []*master_pb.VolumeInformationMessage for _, v := range fullNode.selectedVolumes { candidateVolumes = append(candidateVolumes, v) @@ -389,6 +402,18 @@ func adjustAfterMove(v *master_pb.VolumeInformationMessage, volumeReplicas map[u replica.location.dc == fullNode.dc { loc := newLocation(emptyNode.dc, emptyNode.rack, emptyNode.info) replica.location = &loc + for diskType, diskInfo := range fullNode.info.DiskInfos { + if diskType == v.DiskType { + diskInfo.VolumeCount-- + diskInfo.FreeVolumeCount++ + } + } + for diskType, diskInfo := range emptyNode.info.DiskInfos { + if diskType == v.DiskType { + diskInfo.VolumeCount++ + diskInfo.FreeVolumeCount-- + } + } return } } |
