raft算法

Raft算法:
在分布式系统中,一致性指在集群中的多个节点在状态上达成一致。但是在现实场景中,由于程序奔溃、网络故障、硬件故障等原因,节点的一致性很难保证,这就需要Paxos等一致性协议。
首先Raft核心概念:
leader身份:负责处理接收客户端交互请求,日志复制等,一般情况下只有一个leader。
follower身份:类似选民,完全被动,在探测不到leader存在时,follower在超时时间后会转化为candidate
candidate身份:可以被选举为一个新leader
term :用term作为一个周期,每个term都是一个连续递增的编号,每一轮选举都是一个term周期,在一个term中只能产生一个leader,term也启动系统中逻辑时钟的作用,每一个server当存储了当前term编号,在server之间进行交流的时候就会带上该编号,如果一个server的编号小于另一个,那么它会将自己的编号更新为较大的那一个
如果leader或者condidate发现自己的编号不是最新的,就会自动转变为follower,如果接收到的请求term编号小于自己当前的term将会拒绝执行。
election-timeout:选举超时时间,表示candidate在做下一次竞选之前维持当前状态的时间。
在Raft中使用随机的选举超时,以确保分裂的选票是罕见的,即使出现问题也会很块得到解决,为了防止在第一时间出现分裂投票,Raft集群各个节点之间是通过Rpc通讯传递消息的,每个节点都包含 一个RPC服务端和客户端,初始化时启动RPC服务端,状态设置为follower。
在选举过程中raft有三条规约
1.规定一个节点当选必须要在一个任期内,收到超过半数Follower的投票
2.同一任期内,follower只能投给一个候选人节点,就是说term内只有一次投票机会
3.只能响应任期号大于等于自己任期的请求,比如当前Follower的任期号为5,这个时候来一个任期号为6,Follower就可以投票给他,同事会把自己的任期号改为6,从此以后只接收任期号大于等于6的请求,这样可以处理一种情况,就是我任期5的票投给了节点A,之后又收到节点 B的任期6的请求,因为它的任期更大,所以又把票投给了B,如果A之前没有收到回复,重新发送了任期5的票,这时候会直接得到拒绝的答案。

选举流程:
假设有4个节点,ABCD,当系统刚初始化时,此时没有leader,所有的节点都是Follower
在election_timeout的驱使下,follower会转换成candidate,去拉去选票获取大多数选票后,就当选为leader.首先A增加节点本地的term+1,切换到candidate状态,然后投自己一票,并行给其他节点发送投票,等待其他节点的回复,在这个过程中,根据来自其他节点的消息,可能出现三种结果。
第一中情况:
A收到大部分投票含自己的投票,当选为Leader,A会立刻给所有的节点发送消息,广而告之,避免其余节点触发新的选举。
第二种情况:
被告知其他节点当选,那么自行切换到follower,比如A,b同时发起选举,而B的选举消息先到达C,C给B投了一票,B成为leader后会A,c发送心跳消息,节点A发现节点B的term不低于自己的term,知道已经有leader了于是转换为follower.
第三种情况;
一段时间内节点没有收到大部分投票,则保持candidate状态,重新发出选举。比如A,b同时发起投票,而A拿到AD选票,B拿到了BC选票,也就是Ab同时获取了2张选票,都不满足一半以上的投票要求。针对这种情况,所有节点会在超时完成后,继续发起投票和选举,知道产生leader为止。

总结:
raft协议的优点
1.通过election_timeout一定程度上解决了候选人抢票,导致选举时间过长的问题。
2.更容易工程化

 

Raft一致性算法论文的中文翻译: https://github.com/maemual/raft-zh_cn

posted on 2021-12-07 23:01  云中哥  阅读(126)  评论(0编辑  收藏  举报

导航