Multi-Paxos Raft 原理 流程

Multi-Paxos Raft

前言

分布式一致性算法中鼎鼎有名的Paxos算法,有以下的特点

1、理论上证明了是可靠的

2、但是这个证明,这个原理,是真他喵的难懂😂

3、就算真懂了也很难真正实现

4、有live lock的问题

于是人们实在被搞的烦死了,又发明了另一种Multi-Paxos算法:Raft

Raft,相对于Paxos,特点是:

1、没有理论证明是可靠的

2、容易理解

3、容易实现

4、实践见真知

 

先看动画学个大概

http://thesecretlivesofdata.com/raft/

看懂了大概流程之后,我们可以在这里面玩一下各种情况下最终怎么保持一致性的:

https://raft.github.io/

玩完之后我们来带着一些问题看细节:

当有一个机器挂掉了,落后了好多进度,应该怎么通过这个协议追上来呢?

说明总览图leader视角follower视角数据包

先模拟这个进度落后的情况:

好端端的突然S4掉线了

由于S4挂了,leader拿不到信息了,上次记着他的match index=2,next index = 3

而我们挂掉的S4保存的信息是:commitIndex=2

leader给S4发的请求AppendEntries。prevIndex=2, commitIndex=3,entries=[2]

 

S4知道自己commitIndex=2,然后S1想让S4commitIndex=3,大概意思就是想让S4把3这个entry给填成【2】

然后我们把S4重启 【bring yourself back online 😂】,接收一个来自S1的请求之后

 

然后S1收到了S4的返回,知道S4填好了,就把本地的表给改成S4的match index=3

  

如无意外,这么搞下去很快S4就会追上进度了。那就来点意外吧😂让leader挂掉,咱们换个任期。

    

其他人都收不到leader心跳了,会重新选一个leader

S2作为candidate请求大家给自己投票 
随后S5也想当leader

S2想当leader,S3 S4同意,S5不同意

但是已经获得大多数,S2还是成为了leader;而S5无法获得多数,竞选失败。

这个过程中,各个节点如果认可新leader,应该会把自己的log信息汇报给新leader,新leader更新自己的peers表。

  

 

在这个战乱的时刻,我们来关注一下进度跟不上的S4,

somehow S4的matchindex归为0了

  
然后S4需要向leader汇报自己的进度,最终也就跟上来了   

 

我们再简化一下,只有3个机器

说明&总览S1S2S3
S3经过投票成为leader,然后接受了2个写请求并同步完成followerfollowerleader

让S1挂掉,S3接受2写请求,S1落后进度,这时候S3发4个请求出去,只有1个回,达不到过半数,数据处于半提交状态。

挂掉follower

leader

让S1重新上线,慢慢就恢复了一致性

followerfollowerleader
    

所以这个协议是怎么保证最终的一致性呢,落后进度的情况下,有些节点挂掉的情况下,再重启,怎么就会好了呢?这些都要通过原理来解释

 

然后参考下面视频看看原理

https://www.bilibili.com/video/BV1wt411y7Da/?spm_id_from=333.788.videocard.0

1、客户端给server发送command

2、server使用paxos协议,选择command

3、server等待前一个log entries被applied,然后apply一个新的command到状态机

4、server状态机的结果给客户端。

 

解答以下问题:

来了一个客户端请求,要用哪个log entry?

性能优化:

  • 选个leader来减少proposer 冲突
  • 消除大量的Prepare 请求

保证全部复制好

客户端协议

配置改变

 

注:这个算法其实没有得到严格的证明,说不定有bug。哈哈哈哈

 

当客户端的请求到达的时候:

  • 找到第一个还没被chosen的logEntry
  • 运行basic paxos,propose 客户端的command
  • prepare请求返回了acceptedValue?
    • yes:选择acceptedValue,重新开始
    • no:选择客户端的command

 

如上图,先假设server3掉线了,client command=jmp,发到了server1;

server1找到最小的not chosen index = 3,运行paxos,prepare请求,发现server1已经acceptedValue=cmp,那就接受index=3:cmp,然后重新开始

server1找到最小的not chosen index = 4,运行paxos,prepare请求,发现server2已经acceptedValue=sub,那就接受index=4:sub,然后重新开始

server1找到最小的not chosen index = 5,运行paxos,prepare请求,没发现acceptedValue,终于可以使用client的command。index=5:jmp

选leader:

有最大的id的人当leader

每Tms 每个server发送心跳给其他server

如果一个server在过去的2Tms 没有收到其他server更高的id,他就成为了leader:

  • 可以接受客户端的请求
  • 扮演proposer和Acceptor

如果server不是leader

  • 拒绝客户端请求,转发给leader
  • 只能当Acceptor

 

消除Prepares

为什么需要prepare?

  • 用来block掉老的proposal
    • 让proposal number代表整个log,而不是一个entry

 

有点难懂,未完待续。。。。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值