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 }
// 将一组新的节点(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 }
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 }