Raft协议简介

版权声明:本文为博主原创文章,可以转载但必须注明出处。 https://blog.csdn.net/nirendao/article/details/84933933

作为分布式一致性的算法,Raft相对于Paxos在工程上更易实现。前人曾制作了一篇动画文章,用以简介Raft算法,非常的形象生动。链接在这里:http://thesecretlivesofdata.com/raft/

本文是对该动画文章的一点总结归纳。真正深入了解Raft协议,还是应该看其原论文:https://www.usenix.org/system/files/conference/atc14/atc14-paper-ongaro.pdf

下面是对动画Raft文章的笔记:

基本概念

Raft是用来实现分布式一致性的协议。
一个节点(node)只会是3种状态之一:Follower、Candidate、Leader

Leader选举

简单描述:

所有的nodes最初的时候都是Follower. 如果Follower长时间没有收到Leader的消息,则会变成Candidate. Candidate会发送消息给其他node,让它们投票选举它为Leader. 而这些nodes会回复,并投票选举这个Candidate. 如果一个Candidate得到大多数nodes的投票,则它就当选为Leader. 这个过程就叫做“Leader选举”。

详细描述:

在Raft中,有2种timeout机制影响了Leader选举的过程。
第一种timeout叫“选举超时”(election timeout)。这个“选举超时”定时器被随机设定为150ms-300ms. 在一个Follower上,它的“选举超时”定时器超时后,这个Follower就会变成一个Candidate,然后开始新一轮的选举:这个Candidate会选举它自己,并发送“请选我为Leader”的消息给其他nodes. 接收到该消息的node如果还没有投票,那么就会投票给这个candidate. 一旦一个Candidate有了超过一半的节点选举它,那么它就成为了Leader.

这个Leader就开始发送“Append Entries”(添加系统改变)的message给它的followers. 注意,这些"Append Entries"消息是每隔 heartbeat 超时时间发送一次的。所以,第二种timeout机制就叫做heartbeat timeout,而Append Entries消息也就是Leader发出的心跳消息。Followers会回应每一个"Append Entries"消息作为心跳回应。

如果有一个Follower不再收到心跳消息(即Append Entries消息,其实它有2种功能,一是心跳,二是Leader发出的系统改变信息),那么因为“选举超时”定时器超时,这个Follower就会变成一个Candidate. 比如说,当Leader死掉之后,所有的Followers都不会再收到心跳消息。此时,因为每一个节点上的“选举超时”的定时器都是随机的,所以这些节点的超时时间有先有后。第一个超时的那个,就会发出“请选我为Leader”的消息给所有其他节点;而其他节点超时后,因为收到了这条“请选举我为Leader”的消息,就会选择这个Candidate为Leader.
举个栗子,有3个节点,原来的leader死掉了,剩下的2个Followers的“选举超时”定时器会先后超时,先超时的那个会变成Candidate并发出“请选我为Leader”消息给另一个节点,那个节点的“选举超时”定时器也超时后,就会选这个Candidate为Leader. 因此,3个节点死掉1个的时候,也是可以有Leader被选出来,整个系统是可以继续工作的。

Log Replication

有了Leader之后,所有的系统改变都会通过Leader.
首先,一个client将一个改变发送给Leader. Leader将这个系统改变作为log的一条记录。这一条log记录此时在Leader上还不会被commit,所以它并没有在系统中生效。为了commit这一条改变,在下一次心跳的时候(即心跳计时器超时的时候),Leader把这个改变通过Append Entries消息发送给所有的Followers,然后Leader等待大多数nodes应用这个改变。当大多数Follower应用改变并回复Leader之后,Leader就会commit这条改变并且通知Followers这条改变已经被commit了,也会通知Client该改变已经被应用。此时,集群就达到了一致的状态。这个过程叫做“Log Replication”.

扫描二维码关注公众号,回复: 4738348 查看本文章

脑裂问题

如果有2个节点同时变成了Candidate,并且拥有相同多的支持者时,会怎样呢?
在这种情况下,2个Candidate以及所有的其他节点都会维持现状不动,此时就会导致“选举超时”定时器再一次超时(因为没有Leader发出Append Entries消息),于是这一次这2个Candidate中先超时的那个因为会先发送“请选举我为Leader”消息从而变成Leader.

网络分片下的行为

当网络发生故障,产生分片的时候,Raft也能维持一致性。
假设有ABCDE共5个节点,B为Leader. 现在网络发生故障,产生了2个分区,分区一中只有AB,分区二中只有CDE. 在这种情况下,CDE中因为选举超时,会发生一次选举,进而选出C为Leader;而在AB分区中, B仍然为Leader.

假设现在有2个client. Client-1在AB分区中,发出了一个SET X=3的指令;但因为Node B无法得到大多数节点的ACK,因此它无法commit这条改变;
而Client-2在CDE分区中,发出了一个SET X=8的指令,这条指令会被commit,因为它可以得到大多数节点的支持(译注:包括了它自己)。

将来网络故障修复之后,ABCDE又可以互相访问了,Node B会看到更高的选举版本(higher election term),从而它会把自己降级为Follower,并且A和B会回滚它们没有commit的变化,并采用新Leader的日志所记录的变化。这样,整个系统就又达到了一致。

(完)

猜你喜欢

转载自blog.csdn.net/nirendao/article/details/84933933