Raft 是一个基于 Raft 协议的分布式一致性算法,它实现了一种双向的协作式的领导者选举和成员投票的过程,从而保证了分布式系统的高可用和一致性。Raft 协议在 Data Center 领域有很多的应用,比如 Microsoft 的 Azure 和 AWS,以及 Google 的 Kubernetes。
Raft 协议的核心思想是领导者选举和成员投票。具体来说,系统中的每个节点都会被选举为新的领导者,称为 alpha 节点。alpha 节点会向其所有的 follower 节点广播其选举结果,并开始执行其领导者的职责。同时,alpha 节点还会监听 follower 节点的心跳请求,以确保选举过程的正常进行。当 alpha 节点故障、死亡或者被其 follower 节点选举为新的领导者时,会自动退出领导者职责,并将领导者职责移交给其 follower 节点。
Raft 协议还提供了一种数据一致性的保证机制。具体来说,每个 follower 节点都会在其日志中记录其领导者选举和任期的结果,以确保系统中所有节点都具有相同的历史记录。这种数据一致性保证了在系统出现故障或者节点失效时,仍然可以通过领导者选举和成员投票的过程实现系统的高可用和一致性。
总之,Raft 协议是一种基于领导者选举和成员投票的分布式一致性算法,它能够保证分布式系统的高可用和一致性。在 Data Center 领域,Raft 协议已经被广泛应用,并且在 Microsoft 的 Azure 和 AWS,以及 Google 的 Kubernetes 中都得到了成功的部署和验证。
以上是 Raft 协议中投票和领导选举过程的简要概述。在实际应用中,还需要根据具体情况对协议进行修改和优化,以满足不同的应用场景和需求。
之后,在一系列判断条件之后(后面会讲),节点C会回复节点B的请求信息。插句题外话哈,在B还没收到C的回复消息之前,假设A只是刚刚网络不通畅,现在死而复生,给B发送消息了。那么B发现A的时期比自己落后了,这还等什么?!苍天已死,黄天当立,之后反手将其收为小弟。
之后节点b顺利成为leader。
现在假设有4个节点:A、B、C、D。其中A和D的超时时间是相同的。
150ms过后,A和D同时成为candidate,争相为了成为leader给B和C发消息。
这个时候有对于B和C有两个选择,一个是它们一起支持两个中的一次,也就是要么支持A要么支持D,这样这样其中一个就会成为leader,我们假设它们两个都支持A。
另外一种选择就是,A和D各的一票支持,它们的支持者跟进它们各自的leader的时期,然后本轮选举结束。
之后50ms过去之后,B的超时时间过期了,其获得candiate的资格,这个时候其会向其他follower发送消息请求支持。
之后A、B、D 因为当前的B也没有支持者,所以就会支持B,B顺利成为leader。
当我们的集群leader 选举之后。Leader 接收所有客户端请求,然后转化为 log 复制命令,发送通知其他节点完成日志复制请求。每个日志复制请求包括状态机命令 & 任期号,同时还有前一个日志的任期号和日志索引。状态机命令表示客户端请求的数据操作指令,任期号表示 leader 的当前任期,任期也就是上图中的时期。
而当follower 收到日志复制命令会执行处理流程:
follower 会使用前一个日志的任期号和日志索引来对比自己的数据:
如果相同,接收复制请求,回复 ok;
否则回拒绝复制当前日志,回复 error;
leader 收到拒绝复制的回复后,继续发送节点日志复制请求,不过这次会带上更前面的一个日志任期号和索引;
如此循环往复,直到找到一个共同的任期号&日志索引。此时 follower 从这个索引值开始复制,最终和 leader 节点日志保持一致;
日志复制过程中,Leader 会无限重试直到成功。如果超过半数的节点复制日志成功,就可以任务当前数据请求达成了共识,即日志可以 commite 提交了;
注:
这里要提到的一点就是,如果follower发现canidate的日志还没有自己的新(索引号没自己大),其是不会支持其成为leader的。