コード例 #1
0
ファイル: update_region.go プロジェクト: ksarch-saas/cc
func (self *UpdateRegionCommand) Execute(c *cc.Controller) (cc.Result, error) {
	if len(self.Nodes) == 0 {
		return nil, nil
	}

	// 更新Cluster拓扑
	cs := c.ClusterState
	cs.UpdateRegionNodes(self.Region, self.Nodes)

	// 首先更新迁移任务状态,以便发现故障时,在处理故障之前就暂停迁移任务
	cluster := cs.GetClusterSnapshot()
	if cluster != nil {
		mm := c.MigrateManager
		mm.HandleNodeStateChange(cluster)
	}

	for _, ns := range cs.AllNodeStates() {
		node := ns.Node()
		// Slave auto enable read ?
		if !node.IsMaster() && !node.Fail && !node.Readable && node.MasterLinkStatus == "up" {
			if meta.GetAppConfig().AutoEnableSlaveRead {
				redis.EnableRead(node.Addr(), node.Id)
			}
		}
		// Master auto enable write ?
		if node.IsMaster() && !node.Fail && !node.Writable {
			if meta.GetAppConfig().AutoEnableMasterWrite {
				redis.EnableWrite(node.Addr(), node.Id)
			}
		}
		// Fix chained replication: slave's parent is slave.
		if meta.LocalRegion() == self.Region && !node.IsMaster() {
			parent := cs.FindNode(node.ParentId)
			// Parent is not master?
			if parent != nil && !parent.IsMaster() {
				grandpa := cs.FindNode(parent.ParentId)
				if grandpa != nil {
					_, err := redis.ClusterReplicate(node.Addr(), grandpa.Id)
					if err == nil {
						log.Warningf(node.Addr(), "Fix chained replication, (%s->%s->%s)=>(%s->%s)",
							node, parent, grandpa, node, grandpa)
					}
				} else {
					log.Warningf(node.Addr(), "Found chained replication, (%s->%s->nil), cannot fix.",
						node, parent)
				}
			}
		}

		// 更新Region内Node的状态机
		ns.AdvanceFSM(cs, state.CMD_NONE)
	}

	return nil, nil
}
コード例 #2
0
ファイル: make_replicaset.go プロジェクト: ksarch-saas/cc
// 将一组新的节点(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
}
コード例 #3
0
ファイル: replicate.go プロジェクト: ksarch-saas/cc
func (self *ReplicateCommand) Execute(c *cc.Controller) (cc.Result, error) {
	cs := c.ClusterState
	child := cs.FindNode(self.ChildId)
	parent := cs.FindNode(self.ParentId)
	if child == nil {
		return nil, fmt.Errorf("Child node not exist %s", self.ChildId)
	}
	if parent == nil {
		return nil, fmt.Errorf("Parent node not exist %s", self.ParentId)
	}
	if parent.Fail || child.Fail {
		return nil, ErrNodeIsDead
	}
	// TODO: more check
	_, err := redis.ClusterReplicate(child.Addr(), parent.Id)
	if err != nil {
		return nil, err
	}
	log.Eventf(child.Addr(), "Reparent to %s(%s).", parent.Addr(), parent.Id)
	return nil, nil
}