raft算法基础
1.每一个服务可能有三种状态:领导人、候选人、群众。
领导:负责Client交互和log复制,同一时刻系统中最多存在1个。
群众:被动响应请求RPC,从不主动发起请求RPC。
候选人:一种临时的角色,只存在于leader的选举阶段,某个节点想要变成leader,那么就发起投票请求,同时自己变成candidate。如果选举成功,则变为candidate,否则退回为follower
2.领导选举
如果一个群众没有收到领导人的心跳,他会向其他的群众发起投票机制,如果大多数的群众都投给了他,他就称为了领导人,这个过程叫领导选举。
详解:当服务启动时,所有的节点都是follower,
1、每个节点进行election timeout,第一个到达时间更新自己的任期+1, 转变为候选人
2、这时候发送requestvote rpc给其他的follower节点,
3、收到请求的服务器,在同一任期中会按照先到先投的原则投给至多一个候选人,
4、该节点赢得选举。即收到大多数的节点的投票。则其转变为leader状态。
5、另一个服务器成为了leader。即收到了leader的合法心跳包(term值等于或大于当前自身term值)。则其转变为follower状态。
6、一段时间后依然没有胜者。该种情况下会开启新一轮的选举。
Raft中使用随机选举超时时间来解决当票数相同无法确定leader的问题。
3.有两种时间
election timeout 投票过程中有个选择超时时间在150-300ms
heartbeat timeout 心跳时间内发送
在等待投票的时候,候选人可能会从其他的服务器接收到声明它是领导人的附加日志项 RPC。如果这个领导人的任期号(包含在此次的 RPC中)不
小于候选人当前的任期号,那么候选人会承认领导人合法并回到跟随者状态。 如果此次 RPC 中的任期号比自己小,那么候选人就会拒绝这次的RPC 并且继续保持候选人状态
日志复制
客户端对系统所有的更改都要经过领导人,每一个更改都需要添加到节点中,如果日志还没有提交的话,就不会更新节点的值。领导将日志发给其他群众节点,等到其他大部分的群众节点响应,领导人更新自己的日志条目,领导人通知群众日志已更新提交,集群系统则达成一致性的共识。
选举限制
用来保证复制状态机完善运行。请求投票 RPC 实现了这样的限制: RPC 中包含了候选人的日志信息,然后投票人会拒绝掉那些日志没有自己新的投票请求。
Raft 通过比较两份日志中最后一条日志条目的索引值和任期号定义谁的日志比较新。如果两份日志最后的条目的任期号不同,那么任期号大的日志更加新。如果两份日志最后的条目任期号相同,那么日志比较长的那个就更加新
RPC
Raft 算法中服务器节点之间通信使用远程过程调用(RPCs),并且基本的一致性算法只需要两种类型的 RPCs,为了在服务器之间传输快照增加了第三种 RPC。
RPC有三种:
RequestVote RPC:候选人在选举期间发起
AppendEntries RPC:领导人发起的一种心跳机制,复制日志也在该命令中完成
InstallSnapshot RPC: 领导者使用该RPC来发送快照给太落后的追随者