6.3 转移 Leader
流程详解
流程概览
用户调用
transfer_leadership_to接口转移 Leader若当前 Leader 正在转移或有配置变更正在进行中,则返回
EBUSYLeader 将自身状态设为
Transferring,此时所有的apply会报错,Leader 停止写入,无新增日志判断目标节点日志是否和当前 Leader 一样多:
4.1 如果是的话,向目标节点发送
TimeoutNow请求开始重新选举4.2 否则,继续在后台向 Follower 同步日志,每成功同步一批日志,就重复步骤 4
调用用户状态机的
on_leader_stop启动转移超时定时器;该步骤后,
transfer_leadership_to接口返回成功,但变更仍在继续节点收到
TimeoutNow请求后,并行进行以下 2 件事:7.1 设置
TimeoutNow响应中的term为自身term加一,并发送响应7.2 立马变为
Candidate并自增term进行选举(跳过PreVote阶段)
Leader 收到
TimeoutNow响应后,发现目标节点的term比自身大,则开始step_down成 Follower如果在
election_timeout_ms时间内 Leader 没有step_down,则取消迁移操作:调用状态机的
on_leader_start继续领导当前任期,此时 Leader 的term并未改变将自身状态变为
Leader,并开始重新接受写入请求
相关 RPC
相关接口
阶段一:开始转移 Leader
transfer_leadership_to
用户调用 transfer_leadership_to 开始转移 Leader,其流程见以下注释:
判断差距
ReplicatorGroup::transfer_leadership_to 会在 ReplicatorGroup 找到目标节点的 Replicator,然后调用其 _transfer_leadership 函数。
在 _transfer_leadership 中主要判断目标节点的日志是否和当前 Leader 一样多:
如果是的话,直接进入阶段三发送
TimeoutNow请求进行重新选举否则,保存
lastLogIndex为timeoutNowIndex,并进入阶段二继续同步日志
停止写入
阶段二:同步日志
Replicator 的作用就是不断调用 _send_entries 同步日志,直至 Follower 同步了 Leader 的全部日志才在后台等待,详见<4.1 复制流程>:
同步日志
重判差距
每当收到日志复制的 AppendEntries 响应,都会回调 _on_rpc_returned:
阶段三:重新选举
发送请求
Leader 调用 _send_timeout_now 向目标节点发送 TimeoutNow 请求:
处理请求
Follower 收到 TimeoutNow 请求后,会调用 handle_timeout_now_request 处理请求,具体流程见以下注释:
收到响应
Leader 在收到 TimeoutNow 响应后,会调用 _on_timeout_now_returned 进行 step_down,并在 step_down 函数中移除转移超时定时器:
其他:转移超时
如果在 election_timeout_ms 时间内 Leader 没有 step_down,则转移超时定时器就会超时,调用 on_transfer_timeout 进行处理:
Last updated