Paxos算法
Paxos算法是解决分布式系统中如何就某个值达成协议。典型的场景就是选举主机,zookeeper选举主机使用的zab算法就是Paxos的一个实现。
Paxos的三个角色
- Proposer:提议者,提出方案的角色
- Acceptor:接受者,接收方案的角色
- Learner:学习者,确定接受者是否超过半数的节点同意某个提案
Paxos分为三个阶段
阶段1:发送编号
每一个提议者都会提供一个编号N,并先半数以上的接受者发送编号。
接受者接收到编号后,用伪代码表示
Integer N_p;//提议者编号
Object V_p;//提议者提案
Integer N_a; //接受者编号
Object V_a;//接受者提案
if(N_a==null){
//接收者没有接受过编号
N_a = N_p;
}
else if(N_p<N_a){
//提议者的编号小于接收者的编号,拒绝提议者的编号
return;
}
else{
//接受提议者的编号
N_a = N_p;
if(V_a!=null){
//额外的,如果接受者已经有提案了,那么提议者将自己的提案设置为接受者的提案,否则提议者会在阶段二自己定义提案
V_p = V_a;
}
}
阶段2:发送提案
提议者再次给接受者发送提案
Integer N_p;//提议者编号
Object V_p;//提议者提案
Integer N_a; //接受者编号
Object V_a;//接受者提案
if(N_p<N_a){
//直接拒绝
return;
}
else{
if(V_a!=null){
//通知V_a的原提议者
}
V_a = V_p;
//通知Leaner,当Learner感知到超过半数的接受者接受同一提案时,该提案被最终确定
}
阶段3:决策
当接受者首次接收到一个提案后,会通知学习者(Learner),当学习者观察到有大于N/2+1的接收者接受了同一个方案,那么选举旧结束了。
Raft 算法
Raft把选举拆分为三个字问题:选举,日志一致性,选举安全性。相比于paxos,更容易理解和实现。
角色
- Leader:领导者:负责处理请求和与Follower保持心跳
- Follower:追随者,响应Leader的日志请求,复制领导者的数据,响应Candidate的请求,把请求的事务转发给Leader
- Candidate:候选人,负责选票,当主机下线或者刚启动,Follwer会转换为Candidate发起选举,选举结束后,选举出的Leader会从Candidate转为Leader
Term(任期)
每一个节点都有一个计数器,用于保存Term,当Candidate发起选举时,Term会加一,并向其他节点发送信息,如果其他节点的Term大于发送者的Term,那么会拒绝投票。并且Candidate会更新自己的Term,并转化为Follower,以同步所有节点的任期。
选举过程
- Follower发现自己和Leader的心跳超时了,启动一个计时器(随机时长,为配置时间的1~2倍之间),如果超时时间内,未收到其他节点的AppendEntries,则转换为Candidate。这里设置随机的超时时间,可以避免很多Follwer同时转换为Candidate,避免激烈竞争。
- Term加一,启动计时器,并给自己投一票,向其他所有节点发送RequestVote,并等待其他节点回复。
- 如果其他节点回复了AppendEntries,表示选举已经结束,则转换为Follwer并向新的Leader请求日志同步
- 如果其他节点的Term低于当前的Term且没有投其他节点,那么会投当前节点一票(先到先得)
- 如果计时器结束前,获得了足够的票数(大于N/2+1),那么当前节点备选举为Leader,并向其他节点发送AppendEntries表示结束选举。
- 如果超时时间结束并未选举出Leader,那么重复选举的步骤,进行新一轮的选举。
选举安全性
- 每一个任期内,保证只有一个Leader
- Leader拥有完整的数据,用于使用Term同步,由于被选举的Leader肯定拥有最大的Term,所以也拥有最新的日志。
日志一致性
当有多个Follwer,Leader必须向超过半数的Follwer写入成功,才算提交成功。在下一个心跳,Leader会要求所有的Follower同步这个写入
来源:https://blog.csdn.net/weixin_35885196/article/details/100896843