Esempio n. 1
0
func (self *Inspector) MeetNode(node *topo.Node) {
	for _, seed := range meta.Seeds() {
		if seed.Ip == node.Ip && seed.Port == node.Port {
			continue
		}
		_, err := redis.ClusterMeet(seed.Addr(), node.Ip, node.Port)
		if err == nil {
			break
		}
	}
}
Esempio n. 2
0
// 生成ClusterSnapshot
func (self *Inspector) BuildClusterTopo() (*topo.Cluster, []*topo.Node, error) {
	self.mutex.Lock()
	defer self.mutex.Unlock()
	if len(meta.Seeds()) == 0 {
		return nil, nil, ErrNoSeed
	}

	// 过滤掉连接不上的节点
	seeds := []*topo.Node{}
	for _, s := range meta.Seeds() {
		if redis.IsAlive(s.Addr()) {
			seeds = append(seeds, s)
		} else {
			// remove this seed from meta seeds
			// will re-add to seeds if join the cluster again
			meta.RemoveSeed(s.Addr())
		}
	}

	if len(seeds) == 0 {
		return nil, seeds, ErrNoSeed
	}

	// 顺序选一个节点,获取nodes数据作为基准,再用其他节点的数据与基准做对比
	if self.SeedIndex >= len(seeds) {
		self.SeedIndex = len(seeds) - 1
	}
	var seed *topo.Node
	for i := 0; i < len(seeds); i++ {
		seed = seeds[self.SeedIndex]
		self.SeedIndex++
		self.SeedIndex %= len(seeds)
		if seed.Free {
			glog.Info("Seed node is free ", seed.Addr())
		} else {
			break
		}
	}
	cluster, err := self.initClusterTopo(seed)
	if err != nil {
		glog.Infof("InitClusterTopo failed")
		return nil, seeds, err
	}

	// 检查所有节点返回的信息是不是相同,如果不同说明正在变化中,直接返回等待重试
	if len(seeds) > 1 {
		for _, s := range seeds {
			if s == seed {
				continue
			}
			err := self.checkClusterTopo(s, cluster)
			if err != nil {
				free, node := self.isFreeNode(s)
				if free {
					node.Free = true
					glog.Infof("Found free node %s", node.Addr())
					cluster.AddNode(node)
				} else {
					glog.Infof("checkClusterTopo failed")
					return cluster, seeds, err
				}
			} else {
				s.Free = false
			}
		}
	}

	// 构造LocalRegion视图
	for _, s := range cluster.LocalRegionNodes() {
		if s.PFailCount() > cluster.NumLocalRegionNode()/2 {
			glog.Infof("Found %d/%d PFAIL state on %s, set FAIL",
				s.PFailCount(), cluster.NumLocalRegionNode(), s.Addr())
			s.SetFail(true)
		}
	}

	if meta.IsClusterLeader() {
		cluster.BuildReplicaSets()
	}

	meta.MergeSeeds(cluster.LocalRegionNodes())
	self.ClusterTopo = cluster
	return cluster, seeds, nil
}