分布式选举算法

        分布式系统常见选举算法:基于序号选举的算法(Bully 算法)、多数派算法(Raft 算法、ZAB 算法)等

一、Bully 算法

1、集群节点角色类型

      主节点、普通节点,主节点负责对其他节点的协调和管理

2、选举策略

        在所有活着的节点中,选取 ID 最大的节点作为主节点,当选主成功后,有且仅有一个节点成为主节点,其他所有节点都是普通节点,当且仅当主节点故障或与其他节点失去联系后,才会重新选主。

3、选举过程

a、选举使用到的消息

Election消息: 用于发起选举; Alive消息: 对Election 消息的应答; Victory消息: 竞选成功的主节点向其他节点发送的宣誓主权的消息

b、选举流程

前提条件:集群中每个节点均知道其 他节点的 ID,流程如下:
 

1、集群中每个节点判断自己的ID是否为当前活着的节点中 ID 最大的,如果是,则直接向其他节点发送 Victory 消息,宣誓自己的主权;

2、如果自己不是当前活着的节点中 ID 最大的,则向比自己 ID 大的所有节点发送 Election 消息,并等待其他节点的回复;

3、若在给定的时间范围内,本节点没有收到其他节点回复的 Alive 消息,则认为自己成为 主节点,并向其他节点发送 Victory 消息,宣誓自己成为主节点;若接收到来自比自己 ID 大的节点的 Alive 消息,则等待其他节点发送 Victory 消息;

4、若本节点收到比自己 ID 小的节点发送的 Election 消息,则回复一个 Alive 消息,告知 其他节点,我比你大,重新选举。

应用:MongoDB 的副本集故障转移 功能。MongoDB 的分布式选举中,采用节点的最后操作时间戳来表示 ID,时间戳最新的 节点其 ID 最大,也就是说时间戳最新的、活着的节点是主节点。

总结:谁活着且谁的 ID 最大谁就是主节点,其他 节点必须无条件服从

优点:选举速度快、算法复杂度低、简单易实现

缺点:

        a、每个节点需要存储全部的节点信息,额外的信息存储较多;

        b、任意一个比当前主节点 ID 大的新节点或节点故障后恢复加入集群时,都可能触发重新选举成为新的主节点,如果该节点频繁退出、加入集群,会导致频繁切主。

二、Raft 算法(民主投票)

1、集群节点角色类型

Leader(主节点)

同一时刻只有一个 Leader,负责协调和管理其他节点

Candidate(候选者)

可发起选举

每一种节点都可转化为Candidate节点

此类型节点才可被选为新的leader

Follower(Leader的跟随者)不可以发起选举。

2、选举流程

1. 初始化时,所有节点均为 Follower 状态。

2. 开始选主时,所有节点的状态由 Follower 转化为 Candidate,并向其他节点发送选举请求。

3. 其他节点根据接收到的选举请求的先后顺序,回复是否同意成为主。这里需要注意的是,在每一轮选举中,一个节点只能投出一张票。

4. 若发起选举请求的节点获得超过一半的投票,则成为主节点,其状态转化为 Leader,其他节点的状态则由 Candidate 降为 Follower。Leader 节点与 Follower 节点之间会 定期发送心跳包,以检测主节点是否活着。

5. 当 Leader 节点的任期到了,即发现其他服务器开始下一轮选主周期时,Leader 节点 的状态由 Leader 降级为 Follower,进入新一轮选主。

PS:

1、每一轮选举,每个节点只能投一次票(类似人大代表选举)

2、raft 选主是周期进行的,包括选主阶段(对应投票阶段)、任职阶段; 任职到期、主节点故障会触发重新选举

应用:etcd 的集群管理器 etcds,是一个高可用、强一致性的服务发现存储仓库,就是采用了 Raft 算法来实现选主和一致性的

总结:

        1、算法选举稳定性优于Bully,当新节点加入或节点故障恢复后会触发选主,但不一定会真正切主,除非新节点或故障后恢复的节点获得投票数过半,才会导致切主。

        2、状态流转过程

        

优点:选举速度快、算法复杂度低、易于实现

缺点:要求系统内每个节点都可以相互通信,且需要获得过半的投票数才能选主成功,因此通信量大,

总结:

Raft算法动画分析: http://thesecretlivesofdata.com/raft/#election

三、ZAB 算法

        ZAB(ZooKeeper Atomic Broadcast)选举算法: ZooKeeper 为实现分布式协调功能而设计的。相较于 Raft 算法的投票机制,ZAB算法增加了通过节点 ID 和数据 ID 作为参考 进行选主,节点 ID 和数据 ID 越大,表示数据越新,优先成为主。相比较于 Raft 算法, ZAB 算法尽可能保证数据的最新性。所以,ZAB 算法可以说是对 Raft 算法的改进。

 1、集群节点角色类型与状态

        角色:Leader(主节点)、Follower(跟随者节点)、Observer(观察者,无投票权)

选举过程中的状态

Looking(选举状态)

当节点处于该状态时,认为集群中没有 Leader, 节点会进入选举状态

Leading(领导者状态)

已经选出主,且当前节点为 Leader

Following(跟随者状态)

集群中已经选出主后,其他非主节点状态更新为Following,表示对 Leader 的追随

Observing(观察者状态)

当前节点为 Observer,持观望态度,没有投票 权和选举权

2、选主流程

集群中每个节点都有一个唯一的三元组 (server_id, server_zxID, epoch)

server_id    : 表示本节点的唯一 ID;

server_zxID: 表示本节点存放的数据 ID,数据 ID 越大表示数据越新,选举权重越大;

epoch         : 表示当前选取轮数,一般用逻辑时钟表示

投票:通过 (vote_id, vote_zxID) 来表明投票给哪个节点

vote_id:      被投票节点 ID

vote_zxID: 被投票节点 zxID

ZAB 算法选主的原则是:server_zxID 最大者成为 Leader;若 server_zxID 相同,则 server_id 最大者成为 Leader (核心:“少数服从多数,ID 大的节点优先成为主”)

案例:3个节点的集群选主流程

1、集群启动,3个节点当前投票为第一轮此时 epoch = 1,zxId = 0;此时节点都推选自己,将选票<epoch, vote_id, vote_zxID> 广播出去

2、规则判断,epoch、zxID 都相同,比较 server_id, 较大者为推选对象,此时 1、2节点将vote_id 改为 3,重新广播自己的投票

3、所有节点都推选了 Server 3,Server 3 当选 Leader,处于 Leading 状态并向其他节点发送心跳包维护连接; Server1 和 Server2 处于 Following 状态。

3、总结

        ZAB 算法性能高,对系统无特殊要求,采用广播方式发送信息,若节点中有 n 个节点,每个节点同时广播,则集群中信息量为 n*(n-1) 个消息,容易出现广播风暴;除了投票,还增加了对比节点 ID 和数据 ID,这就意味着还需要知道所有节点的 ID 和数据 ID,所以选举时间相对较长。但该算法选举稳定性比较好,当有新节点加入或节点故障恢复后,会触发选主,但不一定会真正切主,除非新节点或故障后恢复的节点数据 ID 和节点 ID 最大,且获得投票数过半,才会导致切主


问题

1、为什么选主算法通常采用奇数节点,而不是偶数节点 呢?

采用偶数节点集群,当两个节点均获得一半投票时,在这种情况下,无法选出主,必须重新投票选举,关于双主的情况,一般是因为网络故障,比如网络分区等导致的。

更新完善中.....

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值