简单了解 一致性算法 – Raft

2018年8月3日 作者 jacky

Raft的基本概念

角色

在Raft中,任何时候一个服务器可以扮演下面角色之一:

  1. Leader: 处理所有客户端交互,日志复制等,一般一次只有一个Leader.
  2. Follower: 类似选民,完全被动
  3. Candidate候选人: 类似Proposer律师,可以被选为一个新的领导人。

复制状态机(Replicated State Machine)

复制状态机通过复制日志来实现:

  • 日志:每台机器保存一份日志,日志来自于客户端的请求,包含一系列的命令
  • 状态机:状态机会按顺序执行这些命令
  • 一致性模型:分布式环境下,保证多机的日志是一致的,这样回放到状态机中的状态是一致的

Leader elections(Leader选举阶段)

在一开始的时候,每一个节点的初始状态都是Follower(选民),并且每个节点都有自己的计时器,在计时器倒数阶段会监听Candidata(候选人)发送过来的信号。(每个Follower的定时时间是不一样的,随机值在150ms – 300ms之间)

(election term) 选举阶段

当计数器达到选举超时时间(election timeout)都没有接收到候选人发送过来的信号,该节点就会变成Candidate(候选人)。开始进入了选举阶段

进入选举阶段的节点成为了Candidate(候选人),开始为自己投票后。并向所有节点发送请求对方为自己投票的信号。)

当接收到请求投票信号的Flower节点还没有投票,就会给Candidate(候选人)投出宝贵的一票。并且会重置自己的选举计时器,重新计时选举超时时间(election timeout)。

一旦Candidate(候选节点)接受到绝大多数的投票就会变成了Leader(领导者节点)

成为Leader(领导者节点)后,会向其他的Flower(从节点)发送消息(Entries messages),并且这些消息会按心跳超时指定的间隔发送,Flower(从节点)也会响应主节点发送过来的消息。也就是说用这种方式,实现了主从心跳检查。(这个阶段会一直持续,直到Follower节点停止接收心跳检测成为Candidate节点)

假设主节点死了,又进入了选举阶段。

这里假设节点C最早成为了Candidate(候选节点)。根据上面说明,会先给自己投票,然后向其他节点发送请求向自己投票的请求.


那么重复以上的选举阶段,节点C自然成为了Leader节点了。并向其他节点发送心跳检测。

这里有一种情况是,如果2个节点同时成为了Candidate(候选人节点),就会进行分裂投票!

假设节点A和节点C同时成为了Candidate(候选人),他们会同时开始向其他节点发送请求投票信号。

如果这2个Candidate(候选人节点)接收的投票数是一样的,那么就会进入重新选举的阶段。
直到这两个节点的获取的票数不一致,获取多票数的节点便成为了Leader(领导节点)了。


后面的阶段跟上面与其他节点保持心跳的阶段一样。

日志复制

一旦有了Leader(领导节点),就需要复制主节点所有的变动到所有的从节点。我们从上面知道主从是通过发送消息(Entries message)来检测心跳的,同时这些消息也包含了变动消息(也就是需要同步的消息)。

当数据变动追加到Leader(领导节点)的日志中,这个变动数据会在下一次发送心跳检测信息中同步到从节点。

一旦被大多数Foller(从节点)承认这个数据变动,Leader(主节点)就会提交当前数据的变动,同时会反馈给客户端,从而实现数据一致性。

Raft实现动画