您的位置:  首页 > 技术 > 数据库 > 正文

解析分布式云原生数据库中Raft算法的消息类型

2022-04-28 11:00 https://my.oschina.net/u/5148943/blog/5520488 浪潮云溪数据库 次阅读 条评论

浪潮云溪数据库作为新一代分布式数据库,使用Raft共识算法实现多副本之间数据的一致性和外部读取的一致性。在云溪数据库的底层实现中,通过以下几种消息类型实现Raft机制的运行。其中,本地消息指节点创建完消息后,由自身处理该消息。节点间消息指节点在创建完消息后,将消息发送到其他节点并由这些节点处理。

Part 1 - 本地消息

MsgHup

Follower节点持有一个选举计时器,当节点所持有的选举计时器超过预设的选举时间阈值时,便会创建MsgHup消息。具体操作包括:

  • Follower节点调用选举计时器,将选举计数加1;
  • 检查当前Follower节点是否存在于Raft集群内,若不存在,则拒绝创建MsgHup消息。若存在于Raft集群内,则检查选举计数是否大于等于设定的选举时间阈值。若小于设定的选举时间阈值,则拒绝创建MsgHup消息。若满足条件,则创建MsgHup消息。

在创建出MsgHup消息后,当前Follower节点会切换成PreCandidate状态,进入下一步操作。与此同时,PreCandidate节点和Candidate节点也持有一个选举计时器,若PreCandidate节点或Candidate节点持有的选举计时器超过阈值,则会创建MsgHup消息,继续发起预选举或选举。

MsgCheckQuorum

MsgCheckQuorum消息的作用是检测当前Leader节点是否能与Raft集群中的大部分节点通信。Leader节点持有一个心跳计时器,当心跳计时器出现超时现象时,Leader节点便会创建并发送一个MsgCheckQuorum消息。具体操作包括:

  • Leader节点调用心跳计时器,将选举计数加1;
  • 检查选举计数是否大于等于设定的选举时间阈值,若满足条件,则将选举计数置为0,然后创建MsgCheckQuorum消息。

由于MsgCheckQuorum消息属于本地消息,所以当前Leader节点会收到MsgCheckQuorum消息。然后,Leader节点会根据自身记录的其他各个节点的活跃信息,判断该Leader节点与其余节点是否连通。如果不连通的节点数量超过Raft组内节点数量的一半,则节点从Leader状态切换成Follower状态。

MsgBeat

MsgBeat消息的主要作用是探活,由Leader节点创建。在Leader节点所持有的心跳计时器出现超时现象后,便会创建MsgBeat消息。具体操作包括:

  • Leader节点调用心跳计时器,将心跳计数加1;
  • 检查心跳计数是否大于等于设定的心跳时间阈值,若满足条件,则将心跳计数置为0,然后创建MsgBeat消息。

由于MsgBeat消息属于本地消息,所以当前Leader节点会收到MsgBeat消息。然后Leader节点会向其他节点发送MsgHeartbeat心跳消息。若Follower节点收到MsgHeartbeat消息,会重置自身持有的选举计时器,防止发起选举。

MsgTransferLeader

将节点的Leader状态转移到其他Follower节点,该过程涉及对MsgTransferLeader消息和MsgTimeoutNow消息的处理。Leader状态转移,指确定一个Follower节点作为下一个任期的Leader节点。在Leader所在的节点选择出一个合适的Follower节点后,会发送MsgTransferLeader消息交给Leader处理。Leader接收到消息后,具体操作包括:

  • 检测Leader状态转移是否正在进行。
  • 检测Leader状态转移是否已完成。
  • 重置选举计时器。
  • 检测自身记录的目标Follower节点日志情况,若目标Follower节点的日志追加情况与当前Leader节点保持同步,则创建并发送MsgTimeoutNow消息。若不同步,则往目标Follower节点追加日志。

 

Part 2 - 节点间消息

MsgPreVote

当Follower节点接收到MsgHup本地消息时,自身会切换成PreCandidate状态,开始预选举流程。Follower节点创建MsgPreVote消息,并向其他节点广播该消息,其中MsgPreVote消息携带的Term值为节点自身记录的Term值。

集群中其他节点收到MsgPreVote消息后,对MsgPreVote消息的处理包括:

  • 若消息中携带的Term值大于当前节点记录的Term值,则检测该MsgPreVote消息是否为Leader状态转移时发出的消息,以及检测自身记录的Leader节点是否存在,判断当前节点是否参与此次选举。若确定参与此次选举,则当前节点会根据自身的状态,决定是否将同意选票投给MsgPreVote消息的发送节点。
  • 若消息中携带的Term值小于当前节点记录的Term值,则直接向发送MsgPreVote消息的节点投拒绝选票。

MsgPreVoteResp

处于PreCandidate状态的节点会收到集群中其他节点返回的MsgPreVoteResp消息,当PreCandidate节点收到半数以上的同意选票时,便会切换成Candidate状态,发起正式选举。但是,若收到了拒绝选票,且MsgPreVoteResp消息中携带的Term值大于当前节点记录的Term值,则当前节点切换为Follower状态,同时自身记录的Term值置为MsgPreVoteResp消息中携带的Term值,停止接下来的选举流程。

MsgVote

在处于PreCandidate状态的节点收到半数以上的同意选票之后,会发起新一轮的选举,自身会切换成Candidate状态,然后向集群中的其他节点发送MsgVote消息,开始正式选举流程。

MsgVoteResp

在处于Candidate状态的节点接收到MsgVoteResp消息后,对MsgVoteResp消息的处理包括:

  • 若MsgVoteResp消息中携带的Term值大于当前节点记录的Term值,则当前节点切换为Follower状态,同时自身记录的Term值置为MsgPreVoteResp消息中携带的Term值,停止接下来的选举流程。
  • 检测当前节点是否收到了半数以上的同意选票。如果是,则将当前节点切换成Leader状态,然后向集群中其他节点发送消息MsgApp消息。如果不是,则将当前节点切换成Follower状态。

MsgApp

MsgApp消息的作用是Leader节点向集群中其他节点复制Entry记录。在对MsgVote消息处理的过程中,集群中的其他节点已经切换成了Follower状态,并且它们自身记录的Term值与当前Leader节点维护的Term值相同。当Follower节点收到Leader节点发来的MsgApp消息时,会将MsgApp消息中携带的Entry记录追加到raftLog中,然后创建相应的MsgAppResp消息返回给Leader节点。

在处于Follower状态的节点接收到MsgApp消息后,对MsgApp消息的处理包括:

  • 重置选举计时器,防止当前Follower节点发起选举;
  • 设置当前节点记录的Leader信息;
  • 追加Entry记录;

MsgAppResp

不论Follower节点追加Entry成功或失败,均会向Leader节点回复MsgAppResp消息。Leader节点接收到集群中其他Follower节点发送的MsgAppResp响应消息后,会根据自身记录的Follower节点的状态信息,选择不同的追加方式向其追加Entry记录,如单条追加、连续追加。若Leader节点在自身保存的Entery记录中无法找到对应Follower节点需要追加的Entry记录,便会选择发送快照的方式,向其追加Entry。

MsgHeartbeat

在处于Follower状态的节点接收到MsgHeartbeat消息后,对MsgHeartbeat消息的处理包括:

  • 重置选举计时器,防止当前Follower节点发起选举;
  • 设置当前节点记录的Leader信息;
  • 尝试修改当前Follower节点记录的已提交Entry的Index值,检查当前节点是否与Leader节点在Entry记录上存在冲突。若冲突,则将自身的Index信息放到MsgHeartbeatResp消息中,等待发送;
  • 发送MsgHeartbeatResp消息,响应此次心跳。

MsgHeartbeatResp

在处于Leader状态的节点接收到MsgHeartbeatResp消息后,对MsgHeartbeatResp消息的处理包括:

  • 更新相应节点的活跃信息,表明Follower节点与自己是否连通;
  • 若相应节点追加Entry记录的方式为单条追加,则取消单条追加方式;
  • 根据响应消息检测到Follower节点与Leader的Entry记录存在冲突,则调整自身记录的Follower节点状态信息,并向该节点追加Entry记录。
  • 检查到Leader节点中存在未向该Follower节点追加的Entry记录,则向节点发送MsgApp消息完成Entry记录的追加。

MsgProp

客户端通过MsgProp消息向集群发送写请求,而Raft集群中只有Leader节点能够响应客户端的写请求。当集群中的Candidate节点收到客户端发来的MsgProp消息时,会直接忽略该消息。当Follower节点收到MsgProp消息时,会将该MsgProp消息转发给Leader节点。

在处于Leader状态的节点接收到MsgProp消息后,对MsgProp消息的处理包括:

  • 检测MsgProp消息是否携带Entry记录,如果未携带,则输出异常日志并终止程序;
  • 检测当前节点是否被移出集群,如果当前节点以Leader状态被移出集群,则不再处理MsgProp消息;
  • 检测当前Raft集群是否正在进行Leader节点的转移,如果是,则不再处理MsgProp消息;
  • 若上述策略均通过,则将Entry记录保存到当前节点,并通过MsgApp消息向集群中其他节点追加Entry记录。

MsgSnap

在Leader节点尝试向集群中的Follower节点发送MsgApp消息时,如果查找不到相应的Entry记录,就会通过MsgSnap消息将快照数据发送到Follower节点。Follower节点通过快照数据恢复其自身状态,从而可以与Leader节点进行正常的Entry记录追加。

在处于Follower状态的节点接收到MsgSnap消息后,对MsgSnap消息的处理包括:

  • 重置选举计时器,防止当前Follower节点发起选举;
  • 设置当前节点记录的Leader信息;
  • Follower节点根据快照进行恢复,之后向Leader节点回复MsgAppResp消息。

MsgTimeoutNow

该消息与Leader状态转移相关,当Follower节点接收到MsgTimeoutNow消息时,会立刻切换成Candidate状态,然后创建MsgHup消息并发起选举。

 

Part 3 - 小结

本文主要介绍了Raft共识算法在云溪数据库中定义的消息类型,通过上述介绍的消息类型,实现和保证了副本数据的同步。可以看出,云溪数据库中的Raft算法将共识分解成了几个关键模块,例如预选举模块、正式选举模块、探活模块、日志复制模块等。基于此,实现将分布式一致性的复杂问题划分为一系列的模块化问题,大大降低了算法复杂性。

展开阅读全文
  • 0
    感动
  • 0
    路过
  • 0
    高兴
  • 0
    难过
  • 0
    搞笑
  • 0
    无聊
  • 0
    愤怒
  • 0
    同情
热度排行
友情链接