Raft实现一个分布式系统

Raft实现一个分布式系统

Raft中文论文

raft主要包括领导人选举,日志复制和安全性三个方面

领导人选举

Raft 使用一种心跳机制来触发领导人选举。当服务器程序启动时,他们都是跟随者身份。一个服务器节点继续保持着跟随者状态只要他从领导人或者候选者处接收到有效的 RPCs。领导者周期性的向所有跟随者发送心跳包(即不包含日志项内容的附加日志项 RPCs)来维持自己的权威。如果一个跟随者在一段时间里没有接收到任何消息,也就是选举超时,那么他就会认为系统中没有可用的领导者,并且发起选举以选出新的领导者。

要开始一次选举过程,跟随者先要增加自己的当前任期号并且转换到候选人状态。然后他会并行的向集群中的其他服务器节点发送请求投票的 RPCs 来给自己投票。候选人会继续保持着当前状态直到以下三件事情之一发生:(a) 他自己赢得了这次的选举,(b) 其他的服务器成为领导者,© 一段时间之后没有任何一个获胜的人

Raft参数

每个服务实例都要维护一个Raft,具体参数如下

type Raft struct {
	mu            sync.Mutex        
	peers         []*labrpc.ClientEnd 
	persister     *Persister        
	me            int               
	dead          int32              
	state         int             
	currentTerm   int
	leader        bool
	leader_pos    int
	random        *rand.Rand
	electionTimer *time.Timer //超时计数器
}

这里有几点注意的:

  1. 超时计数器使用随机数在150ms-300ms随机出现,目的是为了解决集群领导人选举失败,尝试次数过多的情况
  2. 在更新Raft参数的时候一定要加上互斥锁或者使用aotmic原子更新,因为会出现接受别人投票更新和自己更新同时竞争的情况。

什么样的节点可以成为leader

在集群开始启动时,所有节点都是follower(跟随者)当超时计数器触发后他们的状态变为candidatte(候选人)。
随后向所有节点发送投票,当收到超过一般的投票后,状态变为leader并立刻广播自己是leader的消息,其余节点收到广播将自己的任期和其他参数与leader同步,leader选举完成。

投票会出现的情况

  1. 自己的term比别人的term小,那么别人不会给你投票,并要求你更新自己的term
  2. 自己的term等于别人的term,并且别人的状态为candidate(候选者)那么,别人会给你投票,并且认为你就是他的leader,不再接受小于等于该term的投票了
  3. 自己的term等于别人的term,但是别人的状态为follower(跟随者),不会给你投票(如果没有这个判断会出现集群中没有leader的情况)
  4. 自己的term大于别人的term,不管别人的状态是follower还是candidate,都会给你投票 (如果没有这个判断会出现集群中term不一致的情况)

选举会出现的情况

  1. 当某个节点获得n/2+1个投票后,状态变为leader,并且向所有节点广播这个消息,同时开始维护一个心跳检测,建议100/ms 发送一次
  2. 没有节点获得n/2+1个节点,重置超时计数器等待第二轮投票,因为每一个服务的超时计数器是150-300之间的随机数,所以投票轮数不会太多。

限制

在任何基于领导人的一致性算法中,领导人都必须存储所有已经提交的日志条目。在某些一致性算法中,例如 Viewstamped Replication,某个节点即使是一开始并没有包含所有已经提交的日志条目,它也能被选为领导者。这些算法都包含一些额外的机制来识别丢失的日志条目并把他们传送给新的领导人,要么是在选举阶段要么在之后很快进行。不幸的是,这种方法会导致相当大的额外的机制和复杂性。Raft 使用了一种更加简单的方法,它可以保证所有之前的任期号中已经提交的日志条目在选举的时候都会出现在新的领导人中,不需要传送这些日志条目给领导人。这意味着日志条目的传送是单向的,只从领导人传给跟随者,并且领导人从不会覆盖自身本地日志中已经存在的条目。

Raft 使用投票的方式来阻止一个候选人赢得选举除非这个候选人包含了所有已经提交的日志条目。候选人为了赢得选举必须联系集群中的大部分节点,这意味着每一个已经提交的日志条目在这些服务器节点中肯定存在于至少一个节点上。如果候选人的日志至少和大多数的服务器节点一样新(这个新的定义会在下面讨论),那么他一定持有了所有已经提交的日志条目。请求投票 RPC 实现了这样的限制:RPC 中包含了候选人的日志信息,然后投票人会拒绝掉那些日志没有自己新的投票请求。

Raft 通过比较两份日志中最后一条日志条目的索引值和任期号定义谁的日志比较新。如果两份日志最后的条目的任期号不同,那么任期号大的日志更加新。如果两份日志最后的条目任期号相同,那么日志比较长的那个就更加新。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值