raft实现心得-核心设计

raft核心思想

1、role

角色分为leader、candidate、follower

存在leader时其他节点都为leader的follower
follower一段时间检测不到leader的心跳heartbeat就会变成candidate,并开始投票election选出新的leader

2、heartBeat

leader会定期给其他follower发送heartBeat心跳,确保其他follower知道leader仍然存活,老老实实继续做自己的本分职责

其他follower检测不到heartBeat时,会认为leader已经挂掉,follower会谋反,此时follower会转变成candidate,并发起election选举。follower本地也会不定时发起election。

3、election

在投票过程中,有一个概念叫term任期,本质是一个int型变量,还有一个概念叫voteFor,本质也是一个int,voteFor会记录本节点是否已经给别的节点投票,candidate会首先给自己投一票,并且给其他所有节点发送rpc请求获取投票,如果其他节点收到此rpc请求,会检测此请求的term任期是否比自己高和自己的voteFor是否没有投票,如果高会给其投一票。当节点检测到投票数大于一半节点数,则自己会变成leader,并给其他节点发送heartBeat,其他节点检测到heartBeat后,会变成这个节点的follower。

4、append_Entries

raft集群作为一个高可用服务对外提供服务,如kv数据库等,为了保证集群内各节点的数据一致性leader接收到一个新的服务命令后,会先发送给其他follower,确认有过半的follower接收到该服务命令后,才会把此服务命令标记为已提交commit,leader才会给客户端发送信息:这个命令执行成功。而这个新的服务命令会与heartBeat在一起发送,或者说心跳中会带上新的命令。

5、快速回退

raft集群中由于网络问题,会有很多节点接收不到信息,因为commit的条件是过半的节点接收到信息,少量的节点暂时接收不到信息并不影响raft集群提供服务,但会导致部分节点数据参差不齐,如果某个参差不齐的节点在下个election成为了leader,那么集群的raft一致性相当不存在。快速回退就是在append_Entries时检测通过reply的XIndex、Xterm,试探各个节点中与leader节点第一个term任期冲突的位置,因为第一个冲突前的数据都是相同的,那我们就认为之前的数据时都共有已经commit的数据,leader接收到XIndex与XTerm后,会在下一次append_Entries,把XIndex之后的数据都发给该follower,让其刷盘强制数据一致。

6、persist

每个节点会持久化自己当前状态与所存储日志,以便崩溃时能够恢复为 从前的状态。持久化的数据主要有三个,Log(已提交数据)、currentTerm(当前任期)、votedFor(已投票给谁)。

7、snapshot

快照是为了防止raft运行时间太长导致内存中存不下log数据,所以会定期把已经提交过log数据持久化,已经建立快照的log的index与term用lastIncludedTerm与lastIncludedIndex标记。快照与持久化不同,快照snapshot是把大量的已提交log数据持久化,persist持久化是把raft节点当前数据持久化,persist也要持久化log数据,不过这个log数据是不包括已经snapshot的log数据,而是没有建立快照的内存中该节点暂存的log数据,这些log数据可能已经commit,也可能还没有commit。

你可能感兴趣的:(go语言分布式开发,共识算法)