Raft 协议 - Fabric( 二 )


raft算法支持最大的容错故障节点是(N-1)/2,其中N为集群中总的节点数量 。
对于将用于生产网络的排序服务, 实现了使用 “领导者跟随者” 模型的 Raft 协议,领导者是在一个通道的排序节点集合中动态选择的(这个排序节点集合称为 “共识者集合( set)”),领导者将信息复制到跟随者节点 。
虽然 Raft 提供了许多与 Kafka 相同的功能(尽管它是一个简单易用的软件包)但它与 Kafka 的功能却大不相同,它向引入了许多新的概念,或改变了现有的概念 。
4. Raft 运行流程
节点总是处于以下三种状态之一:跟随者(),候选人()和领导者() 。集群中的一个节点在某一时刻只能是这三种状态的其中一种,这三种角色是可以随着时间和条件的变化而互相转换的 。
Raft 算法主要有两个过程:一个过程是领导者选举,另一个过程是日志复制,其中日志复制过程会分记录日志和提交数据两个阶段 。
4.1 领导者选举
在 Raft 中有两个控制选举的超时设置:选举超时,心跳超时 。
选举超时
所有节点最初都是作为跟随者开始的 。在这种状态下,他们可以接受来自领导者的日志条目(如果其中一个已经当选),或者为领导者投票 。
如果跟随者在一段时间内没有接收到消息,即选举超时(随机150ms - 300ms),节点将自己提升到候选状态,开始新一轮的选举 。
如果跟随者在选举超时时间内收到消息,则会回复消息并重置选举超时时间 。
心跳超时
接下来,系统的所有改变(添加日志记录)都需要经过领导者,即它将开始向跟随者发送“追加记录( )”的消息 。这些消息按照心跳超时指定的时间间隔发送,而跟随者会回复每一条“追加记录”消息,如此往复 。这次的选举会一直持续直到某个跟随者不再接收到心跳,从而变成候选人 。
这个过程就是领导者选举( ) 。
4.2 日志复制
一旦我们选出了领导者,我们就需要将系统的所有改变复制到所有节点上 。这是通过使用与用于心跳的相同的“追加记录”消息来完成的 。
首先,客户端向领导者发送一个改变 。这个改变追加到领导者的日志上,为了提交记录,在下一心跳时,领导者会将改变(日志)发给跟随者,即让跟随者复制日志记录 。
如果日志记录是未提交的,它是不会更新到更新到节点上的,即真正地执行 。当大多数跟随者返回消息并承认,则条目在领导者就会被提交(执行),数据被更新 。
然后领导者会返回回应给客户端,并随着心跳发送消息给跟随者,让它们也提交 。
集群现在已经就系统状态达成了共识 。这个过程就是日志复制 。
在这个过程中只需要领导者发送消息给跟随者节点,跟随者节点返回消息给领导者节点即可完成,跟随者节点之间是无需沟通的 。
所以如果集群总节点数为 n,对于日志记录阶段,通信次数为n-1,对于提交数据阶段,通信次数也为n-1,总通信次数为2n-2,因此raft算法复杂度为O(n) 。
4.3 分区网络的一致性
Raft 甚至可以在面对网络分区时保持一致性 。分区指将节点分为不同的区域,不同区域的节点之间没有通信 。
当对原有网络进行分区,没有领导者的分区会自行产生新的领导者,进行正常的运行 。
当对分区后的网络重新恢复,之前选举的领导者在接收到后来选举的领导者的消息后,会成为它的跟随者 。同时之前的领导者和其跟随者,都将回滚其未提交的条目并匹配新领导者的日志 。
我们的日志现在在集群中是一致的 。
5. 快照