哪些地方使用到了Raft协议:
- mongo primary 选举
一致性算法正是用于解决分布式环境下多副本之间数据一致性的问题的。
- Raft是一种管理复制日志的一致性算法。
-
Raft和Paxos一样只要保证n/2+1节点正常就能够提供服务
-
把算法流程分为三个子问题:
-
选举(Leader election)、
-
日志复制(Log replication)、
-
安全性(Safety)
-
-
-
角色
-
Raft把集群中的节点分为三种状态:Leader、 Follower 、Candidate
-
Raft运行时提供服务的时候只存在Leader与Follower两种状态;
-
-
Leader(领导者):
-
负责日志的同步管理,
-
处理来自客户端的请求,
-
与Follower保持这heartBeat的联系;
-
-
Follower(追随者):
-
刚启动时所有节点为Follower状态,
-
响应Leader的日志同步请求,
-
响应Candidate的请求,
-
把请求到Follower的事务转发给Leader;
-
-
Candidate(候选者):
-
负责选举投票,
-
Raft刚启动时由一个节点从Follower转为Candidate发起选举,
-
选举出Leader后从Candidate转为Leader状态;
-
-
-
Term(可以理解为周期(第几届、任期)的概念)
-
每个Term都是一个连续递增的编号,
-
每一轮选举都是一个Term周期
-
Term的变化流程:
-
Raft开始时所有Follower的Term为1,
-
其中一个Follower逻辑时钟到期后转换为Candidate,
-
Term加1这是Term为2(任期),
-
然后开始选举,
-
-
这时候有几种情况会使Term发生改变:
-
1:如果当前Term为2的任期内没有选举出Leader或出现异常,
-
则Term递增,开始新一任期选举
-
-
2:当这轮Term为2的周期选举出Leader后,
-
过后Leader宕掉了,
-
然后其他Follower转为Candidate,
-
Term递增,开始新一任期选举
-
-
3:当Leader或Candidate发现自己的Term比别的Follower小时
-
Leader或Candidate将转为Follower,Term递增
-
-
4:当Follower的Term比别的Term小时
-
Follower也将更新Term保持与其他Follower一致;
-
-
-
-
-
选举(Election)
-
Raft的选举由定时器来触发,
-
每个节点的选举定时器时间都是不一样的,
-
开始时状态都为Follower
-
某个节点定时器触发选举后Term递增,
-
状态由Follower转为Candidate,
-
向其他节点发起RequestVote RPC请求,
-
这时候有三种可能的情况发生:
-
1:该RequestVote请求接收到n/2+1(过半数)个节点的投票,
-
从Candidate转为Leader,
-
向其他节点发送heartBeat以保持Leader的正常运转
-
-
2:在此期间如果收到其他节点发送过来的AppendEntries RPC请求,
-
如该节点的Term大则当前节点转为Follower,
-
否则保持Candidate拒绝该请求
-
-
3:Election timeout发生则Term递增,
-
重新发起选举
-
-
-
由于每个节点中定时器的时间都是随机的,
-
所以就不会多次存在有多个Candidate同时发起投票的问题。
-
不会大家都不过半的情况
-
-
-
-
有这么几种情况会发起选举,
-
1:Raft初次启动,不存在Leader,发起选举;
-
2:Leader宕机或Follower没有接收到Leader的heartBeat,
-
发生election timeout从而发起选举;
-
-
-
日志复制(Log Replication)
- 日志复制(Log Replication)主要作用是用于保证节点的一致性,
- 这阶段所做的操作也是为了保证一致性与高可用性;
- 这些事务请求或说成命令也就是这里说的日志
- 日志复制(Log Replication)就是为了保证执行相同的操作序列所做的工作
- 在Raft中当接收到客户端的日志(事务请求)后
- 先把该日志追加到本地的Log中,
- 然后通过heartbeat把该Entry同步给其他Follower,
- Follower接收到日志后
- 记录日志然后向Leader发送ACK,
- 当Leader收到大多数(n/2+1)Follower的ACK信息后
- 将该日志设置为已提交并追加到本地磁盘中,
- 通知客户端并在下个heartbeat中
- Leader将通知所有的Follower
- 将该日志存储在自己的本地磁盘中。
安全性(Safety)
- 安全性是用于保证每个节点都执行相同序列的安全机制,
- 如当某个Follower在当前Leader commit Log时变得不可用了,
- 稍后可能该Follower又会被选举为Leader,
- 这时新Leader可能会用新的Log覆盖先前已committed的Log,
- 这就是导致节点执行不同序列;
- Safety就是用于保证选举出来的Leader一定包含先前 commited Log的机制;