#自动选主

# 主备自动选主

在分布式集群节点组和单机一主多备(大于一个备库)部署形态下,可以开启主备自动选主功能来实现主库选举以及故障自动切换。主备自动选主采用Raft算法,并支持设置Quorum。

# 心跳

Raft使用心跳机制来检测数据库状态。领导者角色的数据库会周期性地向所有跟随者发送心跳以维持地位,跟随者只要接收到领导者或候选者的有效心跳或投票消息就会持续保持其跟随者状态。如果一个跟随者在一段时间内没有接收到任何消息(即选举超时),它会认为系统中没有可用的领导者并发起选举以选出新的领导者。

# 任期(Term)

Raft把时间分割成任意长度的任期,用连续的整数标记。每一个任期从一次选举开始,有一个或多个候选者尝试发起投票争取成为领导者。如果一个候选者赢得选举,它就在接下来的任期内担任领导者。在某些情况下,一次选举中的选票可能被多个数据库瓜分,这一任期会以没有领导者结束,然后重新开始一个新的任期(和一次新的选举)。Raft保证了在一个任期内最多只有一个领导者。

# 节点优先级

节点的优先级,值越大表示其节点优先级越高。Raft进行选举操作时,保证数据一致性的前提下,尽可能让集群的高优先级节点成为领导者。

# 选举状态

开启主备自动选主后,数据库在运行时有以下选举状态:

  • 启动(Startup)

    自动选主启动后选举处于启动状态。如果没有其它数据库,则当前数据库直接升为领导者;如果有其它数据库,则切换到预备候选者状态。

  • 跟随者(Follower)

    正常情况下,跟随者会持续接收到领导者发来的心跳消息。每次收到心跳消息,都会重置选举超时时间和最近一次收到心跳的时间(用于投票流程),并且会根据心跳消息更新任期和领导者。如果在一个选举超时周期之内没有收到心跳消息,则会切换到预备候选者状态。

  • 预备候选者和候选者(PreCandidate & Candidate)

    当预备候选者发现它能够获得大多数数据库的选票时,它就会切换到候选者状态。预备候选者和候选者状态的处理逻辑基本是一致的,但预备候选者发起投票时不会增加任期,而候选者会将任期加一。预备候选者避免了由于数据库不稳定而导致任期频繁增加的问题。当一个候选者从大多数数据库获得了针对同一个任期的选票,那么它就赢得了这次选举并成为领导者。每一个数据库最多会对一个任期投出一张选票(按照先到先得的原则),最多只会有一个候选者赢得此次选举。一旦候选者赢得选举,它就成为这一任期的领导者,然后它会向其它数据库发送心跳来确保自己的地位并且阻止产生新的领导者。

  • 领导者(Leader)

    候选者在获得多数数据库的选票之后会切换到领导者状态。领导者会周期性的向其它数据库发送心跳消息。

  • 停止(Shutdown)

    主备自动选主在未启用时选举处于停止状态。

# yasom仲裁选主

在分布式集群节点组和单机一主一备部署形态下,可以开启基于yasom仲裁的选主,当yasom检测到主库发生故障后,触发仲裁切换,将备库升主,继续对外提供业务。原主则由yasom进行降备,启动为备库。

基于yasom的仲裁选主方式有普通模式和零丢失模式:

  • 普通模式

    优先保证可用性,只要有备库存活,都可以在主库故障的情况下进行切换,但不保证数据不丢失。

  • 零丢失模式

    主备优先使用最大保护,保证主库故障后备库切换升主不会丢失数据。如果备库故障,yasom会将主库降为最大可用模式,保证业务不中断。备库恢复后,如果数据同步前主库故障,yasom不会进行仲裁切换,因为此时备库数据不完整。当备库和主库数据再次同步后,yasom会将主库升为最大保护模式。

# 共享集群自动选主

共享集群部署形态下,YCS在感知到系统故障后进行投票仲裁,决定新的主实例以及能留在集群的幸存者列表,并通知所有服务器的所有资源采取必要的重组动作,继续对外提供服务。

# 心跳

共享集群服务通过心跳来感知系统是否出现故障,从而自动触发选主。目前有以下心跳方式:

  • 网络心跳

    实例间通过网络相互发送心跳探测,并根据是否及时收到对方的回应来判断对方实例是否异常。

  • 磁盘心跳

    每个实例往共享存储中当前实例的私有区域定期更新心跳序列号。如果其它实例发现对应实例的心跳序列号没有变更,则判断对应实例异常。

# 任期(Term)

共享集群服务使用任期(Term)来表示产生新的主实例到该主实例失效(主动下线或下次感知到故障)这段时间,共享集群服务按任期来管理各个提供可用服务的周期。

# 选举状态

共享集群服务基于共享存储完成选主过程。实例运行时有以下选举状态:

  • 普通(Normal)

    集群正常运行阶段,实例处于普通状态。实例在启动阶段以及完成了一轮投票仲裁后,会进入到普通状态。

  • 候选者(Candidate)

    实例发现集群服务中没有正常可用的主实例时,会主动将自己切换到候选者状态,并在共享存储上刷新本实例的投票任期。

  • 跟随者(Follower)

    实例发现有其他实例进入了新的投票任期,则将自己切换到跟随者状态,等待最终选主结果。在并发的场景下,集群内可能会存在多个实例处于候选者状态,经过多轮竞争,最后只会留下唯一一个候选者实例,其他实例都会切换到跟随者状态。

  • 计票者(Teller)

    集群内唯一一个候选者实例将自动切换为计票者状态,并根据所有实例的运行状态,选出最合适的实例作为对应任期的主实例(通常是序号最小的实例),并告知其它实例。