Orchestrator 是一款开源的MySQL数据库高可用HA工具。

它稳定可靠,通过分布式的集群部署模式,自身具备容灾能力。

它功能强大,通过周期执行探测SQL,抓取MySQL 实例的基本信息,包括配置信息、复制状态等,可以得到MySQL的拓扑结构topology。并且,可以根据拓扑结构诊断故障analysis failure。

目前,在Github开源社区已有star 4.7k+。

本文对Orchestrator的基本工作原理做简单介绍。

以个人的理解,从整体功能,Orchestrator 分 三大部分:

  • 实例探测 (instances discover/poll)
  • 故障分析(failure analysis)
  • 故障恢复(failure recovery)

下面对每一部分做下说明。

1.实例探测 (instances discover/poll)

Orchestrator会对托管的每个MySQL集群实例,进行周期探测。说探测,实际就是,在MySQL实例上执行探测SQL,抓取实例基本信息。例如,show slave statusshow slave hostsshow master statusshow global status like 'Uptime'等等。

实例探测周期由InstancePollSeconds定义,默认是5s。

在实现上,为了保证实例探测的及时性,采用队列 Queue + 生产者/消费者模式。
首先定义一个Queue用于需要探测的实例。

discoveryQueue = discovery.CreateOrReturnQueue("DEFAULT")

接着,将需要探测的实例push到队列,具体实现在onHealthTick()中。

最后,由消费者(一组goroutine) 进行探测 discovery。具体见handleDiscoveryRequests()

func handleDiscoveryRequests() {
	discoveryQueue = discovery.CreateOrReturnQueue("DEFAULT")

	// create a pool of discovery workers
	for i := uint(0); i < config.Config.DiscoveryMaxConcurrency; i++ {
		go func() {
			for {
				instanceKey := discoveryQueue.Consume()
				// Possibly this used to be the elected node, but has
				// been demoted, while still the queue is full.
				if !IsLeaderOrActive() {
					log.Debugf("Node apparently demoted. Skipping discovery of %+v. "+
						"Remaining queue size: %+v", instanceKey, discoveryQueue.QueueLen())
					discoveryQueue.Release(instanceKey)
					continue
				}

				DiscoverInstance(instanceKey)
				discoveryQueue.Release(instanceKey)
			}
		}()
	}
}

2.故障分析(failure analysis)

通过第一部分的实例周期探测,已经抓取到MySQL 集群的拓扑结构topology,实例之间的复制信息等。

接下来,基于这些信息,就可以诊断故障。
具体过程实现在GetReplicationAnalysis()

例如,根据主库存活情况、从库存活和复制状态,其中故障类型如下:

如果主库异常,并且没有从库,判定为DeadMasterWithoutReplicas

if a.IsMaster && !a.LastCheckValid && a.CountReplicas == 0 {
	a.Analysis = DeadMasterWithoutReplicas
	a.Description = "Master cannot be reached by orchestrator and has no replica"

如果主库异常,并且所有从库存活且复制异常,判定为DeadMaster

 if a.IsMaster && !a.LastCheckValid && a.CountValidReplicas == a.CountReplicas && a.CountValidReplicatingReplicas == 0 {
	a.Analysis = DeadMaster
	a.Description = "Master cannot be reached by orchestrator and none of its replicas is replicating"

如果主库异常,并且所有从库异常,且所有从库复制异常,判定为DeadMasterAndReplicas

if a.IsMaster && !a.LastCheckValid && a.CountReplicas > 0 && a.CountValidReplicas == 0 && a.CountValidReplicatingReplicas == 0 {
	a.Analysis = DeadMasterAndReplicas
	a.Description = "Master cannot be reached by orchestrator and none of its replicas is replicating"

如果主库异常,并且部分从库异常,且所有从库复制异常,判定为DeadMasterAndSomeReplicas

if a.IsMaster && !a.LastCheckValid && a.CountValidReplicas < a.CountReplicas && a.CountValidReplicas > 0 && a.CountValidReplicatingReplicas == 0 {
	a.Analysis = DeadMasterAndSomeReplicas
	a.Description = "Master cannot be reached by orchestrator; some of its replicas are unreachable and none of its reachable replicas is replicating"
}

3.故障恢复(failure recovery)

诊断出故障之后,对于可以进行恢复的,接下来就是故障恢复。
为什么说是,“可以恢复的”?
这是因为,对于某些场景,例如,主库故障,但没有存活从库的情况,是无法进行恢复的。

故障恢复的入口函数是executeCheckAndRecoverFunction()

故障恢复过程如下:

  • 停止所有从库的复制
  • 选出新主库
  • 重建拓扑
  • 提升新主库

每个步骤都可以展开一个小节,在这里就不具体阐述了,有兴趣的可以具体看下代码实现。

4.总结

本文主要介绍了Orchestrator基本工作原理,相信看完之后,一定会有所收获。如果想要了解更多关于Orchestrator的信息,可以前往该开源项目
Github地址 Orchestrator查看。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐