为什么要有分布式选举?
主节点,在一个分布式集群中负责对其他节点的协调和管理,保证其他节点的有序运行。
分布式选举的算法:
- Bully算法:在所有活着的节点中,选取 ID 最大的节点作为主节点。
集群中每个节点均知道其他节点的 ID
节点:主节点和普通节点
三种消息:Election 消息,用于发起选举;Alive 消息,对 Election 消息的应答;Victory 消息,竞选成功的主节点向其他节点发送的宣誓主权的消息。
eg:MongoDB 的副本集故障转移功能。MongoDB 的分布式选举中,采用节点的最后操作时间戳来表示 ID
优点:选举速度快、算法复杂度低、简单易实现。
缺点:需要每个节点有全局的节点信息;
任意一个比当前主节点 ID 大的新节点或节点故障后恢复加入集群的时候,都可能会触发重新选举,成为新的主节点,如果该节点频繁退出、加入集群,就会导致频繁切主。 - Raft算法:少数服从多数
eg:etcd 的集群管理器 etcds
Leader:主节点,同一时刻只有一个 Leader,负责协调和管理其他节点;
Candidate:即候选者,每一个节点都可以成为 Candidate,节点在该角色下才可以被选为新的 Leader;
Follower:Leader 的跟随者,不可以发起选举。
选举流程- 初始化时,所有节点均为 Follower 状态。
- 开始选主时,所有节点的状态由 Follower 转化为 Candidate,并向其他节点发送选举请求。
- 其他节点根据接收到的选举请求的先后顺序,回复是否同意成为主。在每一轮选举中,一个节点只能投出一张票。
- 若发起选举请求的节点获得超过一半的投票,则成为主节点,其状态转化为 Leader,其他节点的状态则由 Candidate 降为 Follower。Leader 节点与 Follower 节点之间会定期发送心跳包,以检测主节点是否活着。
- 当 Leader 节点的任期到了,Leader 节点的状态由 Leader 降级为 Follower,进入新一轮选主。
优点:选举速度快、算法复杂度低、易于实现的优点
缺点:要求系统内每个节点都可以相互通信,且需要获得过半的投票数才能选主成功,因此通信量大
- ZAB算法:相较于 Raft 算法的投票机制,ZAB 算法增加了通过节点 ID 和数据 ID 作为参考进行选主,节点 ID 和数据 ID 越大,表示数据越新,优先成为主。
选举原则:server_zxID 最大者成为 Leader;若 server_zxID 相同,则 server_id 最大者成为 Leader。
server_id 表示本节点的唯一 ID;
server_zxID 表示本节点存放的数据 ID,数据 ID 越大表示数据越新,选举权重越大;
epoch 表示当前选取轮数,一般用逻辑时钟表示。
优点:稳定性比较好,性能高。
缺点:每个节点同时广播,每个节点同时广播。对比节点 ID 和数据 ID,需要知道所有节点的 ID 和数据 ID,所以选举时间相对较长。
eg:ZooKeeper 实现分布式协调功能