ETCD - RAFT
Raft介绍 - 一个易于理解和实现的共识算法
- Raft 集群中每一台服务器只可能处于 Leader、Follower 以及 Candidate 三种状态;在处于正常的状态时,集群中只会存在一个 Leader,其余的服务器都是 Follower。
- 所有的 Follower 节点都是被动的,它们不会主动发出任何的请求,只会响应 Leader 和 Candidate 发出的请求,对于每一个用户的可变操作,都会被路由给 Leader 节点进行处理,Candidate 节点其实只是集群运行过程中的一个临时状态。
- Raft 集群中的时间也被切分成了不同的几个任期(Term),每一个任期都会由 Leader 的选举开始,选举结束后就会进入正常操作的阶段,直到 Leader 节点出现问题才会开始新一轮的选择。
- 每一个服务器都会存储当前集群的最新任期,它就像是一个单调递增的逻辑时钟,能够同步各个节点之间的状态,当前节点持有的任期会随着每一个请求被传递到其他的节点上。
- Raft 协议在每一个任期的开始时都会从一个集群中选出一个节点作为集群的 Leader 节点,这个节点会负责集群中的日志的复制以及管理工作。
Raft 协议三个子问题
- 节点选举
- 日志复制
- 安全性
定时器与心跳
- 使用 Raft 协议的 etcd 集群在启动节点时,会遵循 Raft 协议的规则,所有节点一开始都被初始化为 Follower 状态。
- 当 Follower 接受到了来自 Leader 的 RPC 消息时,会将当前节点的选举超时时间重置并 通知 Leader 当前节点能够正常运行。
- Candidate 收到心跳请求时都会重置节点的选举超时时间,并将节点的状态直接转变成 Follower。
- Leader 节点收到心跳的响应时就会将对应节点的状态设置为 Active。
节点竞选
- 如果 Follower 节点在一段时间内没有收到来自 Leader 节点的消息就会尝试发起竞选。它会将票投给自己,如果当前集群只有一个节点,该节点就会直接成为集群中的 Leader 节点
- 如果当前节点投的票就是消息的来源或者当前节点没有投票也没有 Leader,那么就会向来源的节点投票,否则就会通知该节点当前节点拒绝投票。
- Candidate 每当收到一个 MsgVoteResp 类型的消息时,就会设置当前节点持有的 votes 数组,更新其中存储的节点投票状态并返回投『同意』票的人数,如果获得的票数大于法定人数 quorum,当前节点就会成为集群的 Leader 并向其他的节点发送当前节点当选的消息,通知其余节点更新 Raft 结构体中的 Term 等信息。