Esempio n. 1
0
func GenerateRebalancePlan(method string, cluster *topo.Cluster, targetIds []string, ratio int) ([]*MigratePlan, error) {
	rss := cluster.ReplicaSets()
	regions := meta.AllRegions()

	ss := []*topo.Node{}          // 有slots的Master
	tm := map[string]*topo.Node{} // 空slots的Master

	for _, rs := range rss {
		master := rs.Master
		// 忽略主挂掉和region覆盖不全的rs
		if master.Fail || !rs.IsCoverAllRegions(regions) || master.Free {
			continue
		}
		if master.Empty() {
			tm[master.Id] = master
		} else {
			ss = append(ss, master)
		}
	}
	if method == "mergetail" {
		merger := MergerTable[method]
		if merger == nil {
			return nil, fmt.Errorf("Rebalancing method %s not exist.", method)
		}
		plans := merger(ss, 0)
		return plans, nil
	} else if method == "mergeall" {
		merger := MergerTable[method]
		if merger == nil {
			return nil, fmt.Errorf("Rebalancing method %s not exist.", method)
		}
		plans := merger(ss, ratio)
		return plans, nil
	} else {

		var ts []*topo.Node
		// 如果没传TargetId,则选择所有可以作为迁移目标的rs
		if len(targetIds) == 0 {
			for _, node := range tm {
				ts = append(ts, node)
			}
		} else {
			for _, id := range targetIds {
				if tm[id] == nil {
					return nil, fmt.Errorf("Master %s not found.", id)
				}
				ts = append(ts, tm[id])
			}
		}

		if len(ts) == 0 {
			return nil, fmt.Errorf("No available empty target replicasets.")
		}

		rebalancer := RebalancerTable[method]
		if rebalancer == nil {
			return nil, fmt.Errorf("Rebalancing method %s not exist.", method)
		}
		plans := rebalancer(ss, ts)
		return plans, nil
	}
	return nil, nil
}