知识贴:分布式算法Raft

Posted 我们全都爱学习

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识贴:分布式算法Raft相关的知识,希望对你有一定的参考价值。

Raft算法


前面我们介绍过分布式系统的经典算法Paxos,但是由于Paxos协议的复杂性其难于理解,更难以实现,Google的分布式锁系统Chubby作为Paxos实现曾经遭遇到很多坑。


而Raft是一个来自Stanford的新的分布式协议,相对于Paxos它显得更为简洁,更注重协议的落地性和可理解性;目前已经有各种语言的实现版本,并被广泛使用。


Raft的角色


  • Leader: 处理所有客户端交互,日志复制等;系统只有一个Leader。

  • Follower: 跟随者,处理日志备份。

  • Candidate: 只在选举阶段出现,表示可以被选为一个新的Leader。


Leader和Follower的交互通过Heartbeats消息传递,一个heartbeat消息可以包含,也可以不包含LogEntries数据。


Raf的运行阶段

  • 选举阶段,选举新的Leader。

    • 每一个Leader都有一个任期(Term)概念,从开始选举算起。

    • 每次选举需要超过半数的成员通过(N/2)+1,节点可以投票自己。

  • 服务阶段,在Leader的领导下,提供客户端服务,日志复制等操作。



Leader投票选举过程


  1. 如果follower在一定时间周期(即选举超时election timeout)内没有收到leader的heartbeat消息,那么follower会认为leader已经宕机。开启一个新的选举。

  2. 首先产生一个新的任期(即把term值加1),然后把自己标记为状态candicate,并给自己投票。

  3. 接着向其他节点发送投票请求RequestVote,并等待回复。

    1. 对于收到投票请求的节点,如果在这轮(term)投票周期中没有投过其他节点票,那么就把票投给它(先来先服务的原则)。

    2. 同时这些收到投票请求的节点也不再把自己状态改为candicate。

    3. 而已经改为candicate的节点则不会为其他节点做出投票操作,因为一开始他们就把票投给自己了。

  4. 然后candicate会有三种可能性:

    1. 在选举超时之前得到超过半数的回复数量,则转化为leader。

    2. 在选举超时之前没有得到超过半数的回复数列,说明有多个follower同时变为candicate,而没有一个人得到超过半数的票数(这叫脑裂),则sleep一个随机值(间隔150毫秒到300毫秒);重新发起新一轮投票(term值会再加1)。

    3. 在选举超时之前收到其他leader的heartbeat消息,说明已经选出了新leader,则接受新的leader,把自己标记为follower。

  5. 选出leader后

    1. Leader会定期发送heartbeat(append entries)消息到所有的followers,这个发送周期是heartbeat timeout。

    2. Follower收到来自leader的heartbeats消息后要回复这些消息。


这里我们要先介绍一些节点的启动过程,因为启动过程会伴随着首次选举的发生:

  1. 节点启动的时候把自己标记为follower。

  2. Follower节点在启动超时之前,如果收到leader的heartbeat消息,则说明已经有leader了。

  3. 如果超时之前没有收到leader的heartbeat消息,说明没有leader,则把自己标记为candicate,开始一轮选举过程。


日志复制(Log Replication)


当一个节点被选举为leader之后,他就开始接收所有客户端的请求(在有些系统中客户端也会把请求发送给follower,但这时follower并不做任何事,只起一个proxy的作用,直接把请求转发给leader)。


  1. Leader为每一个客户端请求创建一个entry以append的方式添加到日志里。此时entry的状态是uncommitted, 它不会更改节点的状态,只是记录到日志里。

    1. Raft节点的日志是由一个个enty以串行的方式组织而成。

    2. 每个entry有一个序号,序号是连续递增不能有空缺。

    3. 日志只增不减,也不能修改。

    4. 日志有一个状态标记信息(entry序号),标志在这个序号之前的所有entry已经提交了,而在这个序号之后的enry还都没有提交。

  2. Leader节点然后在下一个heartbeat消息里把当前entry复制到所有的follower节点。

  3. Follower节点收到来自leader的entry消息后,也添加到自己节点的日志里面,同样不改状态,并回复leader。

  4. 如果leader收到超过半数的回复,说明这个复制操作成功,接着更新节点的状态,变成committed,然后回复客户端。

  5. Leader再通知follower当前请求已经提交了,然后follower也提交各自的请求,最终所有节点状态都发生改变,最终保持状态一致。




以上是关于知识贴:分布式算法Raft的主要内容,如果未能解决你的问题,请参考以下文章

分布式共识算法——Raft算法(图解)

分布式共识算法——Raft算法(图解)

分布式一致性算法:Raft 算法

分布式一致性算法:Raft 算法(Raft 论文翻译)

分布式共识算法-Raft算法

浅谈分布式共识算法Raft