3种状态:Leader(领袖)Follower(群众)Candidate(候选人)。
规则:群众发起投票成为候选人,候选人得到大多数票至少(n/2)+1,才能成为领导人,(自己可以投自己,当没有接受到请求节点的选票时,发起投票节点才能自己选自己),领导人负责处理所有与客户端交互,是数据唯一入口,协调指挥群众节点。
选举过程:考虑最简单情况,abc三个节点,每个节点只有一张票,当N个节点发出投票请求,其他节点必须投出自己的一票,不能弃票,最差的情况是每个人都有一票,那么随机设置一个timeout时间,就像加时赛一样,这时同时的概率大大降低,谁最先恢复过来,就向其他两个节点发出投票请求,获得大多数选票,成为领导人。选出 Leader 后,Leader 通过定期向所有 Follower 发送心跳信息维持其统治。若 Follower 一段时间未收到 Leader 的心跳则认为 Leader 可能已经挂了再次发起选主过程。
保持一致性过程:
1.第一步时,L节点挂掉,不影响一致性,从新选举新的节点就好
2.第二步时,数据到达L节点但未复制给群众节点,L节点挂掉,client无法接收到ACK(4.1步返回的消息),这个阶段 Leader 挂掉,数据属于未提交状态,Client 不会收到 Ack 会认为超时失败可安全发起重试。Follower 节点上没有该数据,重新选主后 Client 重试重新提交可成功。原来的 Leader 节点恢复后作为 Follower 加入集群重新从当前任期的新 Leader 处同步数据,强制保持和 Leader 数据一致。
3.数据到达L节点复制给F节点此时L节点挂掉,这个阶段 Leader 挂掉,虽然数据在 Follower 节点处于未提交状态(Uncommitted)但保持一致,重新选出 Leader 后可完成数据提交,此时 Client 由于不知到底提交成功没有,可重试提交。针对这种情况 Raft 要求 RPC 请求实现幂等性,也就是要实现内部去重机制。
4.数据到达L节点成功复制给部分F节点,此时L节点挂掉,这个阶段 Leader 挂掉,数据在 Follower 节点处于未提交状态(Uncommitted)且不一致,Raft 协议要求投票只能投给拥有最新数据的节点。所以拥有最新数据的节点会被选为 Leader 再强制同步数据到 Follower,数据不会丢失并最终一致。
5.数据到达L节点成功复制给大多数F节点,并接受到F节点的确认信息,F节点未接受到提交信息,此时L挂掉,这个阶段 Leader 挂掉,重新选出新 Leader 后的处理流程和阶段 3 一样。
6.4.1步骤未做但是4.2步骤已做,这个阶段 Leader 挂掉,Cluster 内部数据其实已经是一致的,Client 重复重试基于幂等策略对一致性无影响。
7.网络问题导致多L节点,网络分区将原先的 Leader 节点和 Follower 节点分隔开,Follower 收不到 Leader 的心跳将发起选举产生新的 Leader。这时就产生了双 Leader,原先的 Leader 独自在一个区,向它提交数据不可能复制到多数节点所以永远提交不成功。向新的 Leader 提交数据可以提交成功,网络恢复后旧的 Leader 发现集群中有更新任期(Term)的新 Leader 则自动降级为 Follower 并从新 Leader 处同步数据达成集群数据一致。
转载请注明:SuperIT » 分布式算法之选举算法Raft