@ -6,6 +6,7 @@ import (
"fmt"
"fmt"
"io"
"io"
"os"
"os"
"strings"
"time"
"time"
"github.com/seaweedfs/seaweedfs/weed/pb"
"github.com/seaweedfs/seaweedfs/weed/pb"
@ -32,7 +33,7 @@ func (c *commandVolumeBalance) Name() string {
func ( c * commandVolumeBalance ) Help ( ) string {
func ( c * commandVolumeBalance ) Help ( ) string {
return ` balance all volumes among volume servers
return ` balance all volumes among volume servers
volume . balance [ - collection ALL_COLLECTIONS | EACH_COLLECTION | < collection_name > ] [ - force ] [ - dataCenter = < data_center_name > ]
volume . balance [ - collection ALL_COLLECTIONS | EACH_COLLECTION | < collection_name > ] [ - force ] [ - dataCenter = < data_center_name > ] [ - racks = rack_name_one , rack_name_two ] [ - nodes = 192.168 .0 .1 : 8080 , 192.168 .0 .2 : 8080 ]
Algorithm :
Algorithm :
@ -73,6 +74,8 @@ func (c *commandVolumeBalance) Do(args []string, commandEnv *CommandEnv, writer
balanceCommand := flag . NewFlagSet ( c . Name ( ) , flag . ContinueOnError )
balanceCommand := flag . NewFlagSet ( c . Name ( ) , flag . ContinueOnError )
collection := balanceCommand . String ( "collection" , "ALL_COLLECTIONS" , "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" )
dc := balanceCommand . String ( "dataCenter" , "" , "only apply the balancing for this dataCenter" )
racks := balanceCommand . String ( "racks" , "" , "only apply the balancing for this racks" )
nodes := balanceCommand . String ( "nodes" , "" , "only apply the balancing for this nodes" )
applyBalancing := balanceCommand . Bool ( "force" , false , "apply the balancing plan." )
applyBalancing := balanceCommand . Bool ( "force" , false , "apply the balancing plan." )
if err = balanceCommand . Parse ( args ) ; err != nil {
if err = balanceCommand . Parse ( args ) ; err != nil {
return nil
return nil
@ -84,12 +87,12 @@ func (c *commandVolumeBalance) Do(args []string, commandEnv *CommandEnv, writer
}
}
// collect topology information
// collect topology information
topologyInfo , _ , err := collectTopologyInfo ( commandEnv , 1 5* time . Second )
topologyInfo , _ , err := collectTopologyInfo ( commandEnv , 5 * time . Second )
if err != nil {
if err != nil {
return err
return err
}
}
volumeServers := collectVolumeServersByDc ( topologyInfo , * dc )
volumeServers := collectVolumeServersByDcRackNode ( topologyInfo , * dc , * racks , * nodes )
volumeReplicas , _ := collectVolumeReplicaLocations ( topologyInfo )
volumeReplicas , _ := collectVolumeReplicaLocations ( topologyInfo )
diskTypes := collectVolumeDiskTypes ( topologyInfo )
diskTypes := collectVolumeDiskTypes ( topologyInfo )
@ -142,13 +145,19 @@ func balanceVolumeServersByDiskType(commandEnv *CommandEnv, diskType types.DiskT
return nil
return nil
}
}
func collectVolumeServersByDc ( t * master_pb . TopologyInfo , selectedDataCenter string ) ( nodes [ ] * Node ) {
func collectVolumeServersByDcRackNode ( t * master_pb . TopologyInfo , selectedDataCenter string , selectedRacks string , selectedNodes string ) ( nodes [ ] * 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 {
if selectedRacks != "" && ! strings . Contains ( selectedRacks , r . Id ) {
continue
}
for _ , dn := range r . DataNodeInfos {
for _ , dn := range r . DataNodeInfos {
if selectedNodes != "" && ! strings . Contains ( selectedNodes , dn . Id ) {
continue
}
nodes = append ( nodes , & Node {
nodes = append ( nodes , & Node {
info : dn ,
info : dn ,
dc : dc . Id ,
dc : dc . Id ,
@ -325,7 +334,6 @@ func attemptToMoveOneVolume(commandEnv *CommandEnv, volumeReplicas map[uint32][]
}
}
func maybeMoveOneVolume ( commandEnv * CommandEnv , volumeReplicas map [ uint32 ] [ ] * VolumeReplica , fullNode * Node , candidateVolume * master_pb . VolumeInformationMessage , emptyNode * Node , applyChange bool ) ( hasMoved bool , err error ) {
func maybeMoveOneVolume ( commandEnv * CommandEnv , volumeReplicas map [ uint32 ] [ ] * VolumeReplica , fullNode * Node , candidateVolume * master_pb . VolumeInformationMessage , emptyNode * Node , applyChange bool ) ( hasMoved bool , err error ) {
if ! commandEnv . isLocked ( ) {
if ! commandEnv . isLocked ( ) {
return false , fmt . Errorf ( "lock is lost" )
return false , fmt . Errorf ( "lock is lost" )
}
}