Ejemplo n.º 1
0
// 将一组新的节点(Master,NotFail,NoSlots)设置成一个ReplicaSet
// 需要保证节点覆盖所有Region
func (self *MakeReplicaSetCommand) Execute(c *cc.Controller) (cc.Result, error) {
	cs := c.ClusterState

	masterNodeId := ""
	masterRegion := meta.MasterRegion()
	regions := meta.AllRegions()

	regionExist := map[string]bool{}
	for _, r := range regions {
		regionExist[r] = false
	}

	// 检查节点状态
	for _, nodeId := range self.NodeIds {
		node := cs.FindNode(nodeId)
		if node == nil {
			return nil, ErrNodeNotExist
		}
		if node.Fail {
			return nil, fmt.Errorf("Node %s has failed", nodeId)
		}
		if !node.IsMaster() {
			return nil, fmt.Errorf("Node %s is not master, newly added node must be master.", nodeId)
		}
		if len(node.Ranges) != 0 {
			return nil, fmt.Errorf("Node %s is not empty, newly added node must be empty.", nodeId)
		}
		regionExist[node.Region] = true

		if node.Region == masterRegion {
			masterNodeId = nodeId
		}
	}

	// 检查地域覆盖
	for region, exist := range regionExist {
		if exist == false {
			return nil, fmt.Errorf("Lack node in region %s", region)
		}
	}

	// 设置主从关系
	for _, nodeId := range self.NodeIds {
		if nodeId == masterNodeId {
			continue
		}
		node := cs.FindNode(nodeId)
		_, err := redis.ClusterReplicate(node.Addr(), masterNodeId)
		if err != nil {
			return nil, fmt.Errorf("Set REPLICATE failed(%v), please set relationship manually.", err)
		}
	}
	return nil, nil
}
Ejemplo n.º 2
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
}