本地编译
参考:https://blog.csdn.net/heartsdance/article/details/119737124
elasticsearch启动过程
@startuml
!theme plain
Node -[#red]> GatewayMetaState: start()
Node -[#red]> Coordinator: doStart() 设置coordinationState 协调状态
Node -[#red]> TransportService : acceptIncomingRequests()=true开始接受请求
Node -[#red]> Coordinator : startInitialJoin()开始加入集群
Coordinator -[#red]> Coordinator : becomeCandidate()成为候选者
Coordinator -[#red]> CoordinatorPeerFinder:activate()
CoordinatorPeerFinder -[#red]> CoordinatorPeerFinder:handleWakeUp() 启动周期性监控节点更新
Coordinator -[#red]> Coordinator : onFoundPeersUpdated()查找节点变更 节点mode 是否变更为CANDIDATE 并进行投票
Coordinator -[#red]> ClusterBootstrapService:onFoundPeersUpdated()集群引导
Coordinator -[#red]> ClusterBootstrapService:startBootstrap()开始集群引导 如果执行过不再执行 bootstrappingPermitted = false
ClusterBootstrapService -[#red]> ClusterBootstrapService:doBootstrap()
ClusterBootstrapService -[#red]> Coordinator:setInitialConfiguration()
alt getStateForMasterService().getLastAcceptedConfiguration() 为空Coordinator -> CoordinationState:setInitialState()设置ClusterState
Coordinator -> PreVoteCollector:update()更新预投票的响应
Coordinator -> Coordinator:startElectionScheduler() 启动选举
Coordinator -> ElectionSchedulerFactory:electionScheduler = startElectionScheduler() 创建选举调度器
ElectionSchedulerFactory -> PreVoteCollector:start()开始选举
PreVoteCollector -> PreVotingRound:start() 广播其他节点开始投票end
@enduml
选举
@startuml
!theme plain
NodeA -[#red]> NodeB: internal:cluster/request_pre_vote: PreVoteRequest(transportService.getLocalNode(), currentTerm)NodeB -> PreVoteCollector:handlePreVoteRequest()
PreVoteCollector -> NodeB:PreVoteResponse()
NodeB -[#red]> NodeA:PreVoteResponse(currentTerm,lastAcceptedTerm,lastAcceptedVersion)
NodeA -> PreVoteCollector:handlePreVoteResponse()
alt response.lastAcceptedTerm > NodeA.term ||\n(response.lastAcceptedTerm==NodeA.term&&\nresponse.lastAcceptedVersion>NodeA.VersionOrMetaDataVersion)PreVoteCollector -> NodeA: 比本节点的高 丢弃预选票
else 比本节点的高低(term version)
PreVoteCollector -> PreVoteCollector: preVotesReceived.put(sender, response)收集请求
PreVoteCollector -> PreVoteCollector : voteCollection.addJoinVote()收集选票
alt ElectionStrategy.isElectionQuorum(voteCollection)是获得多数预选票==false
PreVoteCollector -> NodeA: 没收集到足够的预选票 返回
else 获得多数的预选票 开始选举
PreVoteCollector -> Coordinator: startElection
NodeA -[#red]> NodeB: 通知其他节点可以选我作为term+1进入下一个纪元 leaderinternal:internal:cluster/coordination/start_join:StartJoinRequest(getLocalNode(), Math.max(getCurrentTerm(), maxTermSeen) + 1)NodeB->Coordinator:joinLeaderInTerm() 和本地节点比较
Coordinator->CoordinationState:handleStartJoin()处理加入请求
alt startJoinRequest.getTerm() <= getCurrentTerm()
CoordinationState->Coordinator: request的term小于本地的直接返回
else
CoordinationState->CoordinationState:更新本地persistedState.setCurrentTerm(startJoinRequest.getTerm()) 清理之前的收集的选票
endCoordinator->NodeB:optionalJoin=Join(localNode,startJoinRequest.getSourceNode(),getCurrentTerm(), getLastAcceptedTerm())
NodeB-[#red]>NodeA:选我作为leader的选票响应internal:cluster/coordination/join:JoinRequest(transportService.getLocalNode(), optionalJoin)
NodeA->Coordinator:handleJoinRequest(JoinRequest)
Coordinator->Coordinator:processJoinRequest()
Coordinator->CoordinationState:handleJoin()
Coordinator->Coordinator:ensureTermAtLeast() 如果检测到 其他加入节点的版本高于本地 这放弃本次投票 加入到更高的投票中去 出现这种原因是因为预投票是多投票
alt coordinationState.get().electionWon() 节点已经是leader
Coordinator->Coordinator: handleJoinIgnoringExceptions()
else
Coordinator->CoordinationState:收集选票joinVotes.addJoinVote(join)
CoordinationState->CoordinationState:electionWon=isElectionQuorum(VoteCollection joinVotes) 判断是否获得多数的选票
alt prevElectionWon == false && coordState.electionWon() 获得多数选票
Coordinator->Coordinator: becomeLeader() 成为leader mode = Mode.LEADER
Coordinator->CandidateJoinAccumulator:close()关闭Candidate mode进入leader
CandidateJoinAccumulator->MasterService:submitStateUpdateTasks() 提交更新任务
MasterService->Batcher:submitTasks()批量任务提交
Batcher->UpdateTask:run()执行任务
UpdateTask->Batcher:run()
Batcher->MasterService:runTasks()执行批量任务
MasterService->MasterService:calculateTaskOutputs()检测集群状态是否有变更
alt askOutputs.clusterStateUnchanged() 集群状态没有变更
else
MasterService->Coordinator:publish(ClusterChangedEvent,startTimeMillis) 发集群状态变更事件
Coordinator->CoordinationState:组装 PublishRequest
Coordinator->Coordinator: 创建CoordinatorPublication 用于广播其他节点
CoordinatorPublication->CoordinatorPublication:new 注册AckListener响应请求,timeoutHandler 注册发布超时监控
Coordinator->CoordinatorPublication:start()
CoordinatorPublication->PublicationTarget:sendPublishRequest() forEach 广播通知其他节点
PublicationTarget->Publication:sendPublishRequest() responseActionListener=new PublishResponseHandler() 设置ResponseHandler
end
end
end
end
@enduml
发布
@startuml
!theme plain
Master-> Publication:start() forEach
Publication-> PublicationContext:sendPublishRequest()
alt sendFullVersion || !previousState.nodes().nodeExists(destination) 全量发送
PublicationContext->PublicationTransportHandler: sendFullClusterState()
else diff 发送
PublicationContext->PublicationTransportHandler:sendClusterStateDiff()
endMaster -[#red]> NodeB: internal:internal:cluster/coordination/publish_state: BytesTransportRequest(bytes, node.getVersion())
NodeB -> Coordinator:handlePublishRequest()
Coordinator -> CoordinationState:handlePublishRequest()
CoordinationState->Coordinator:PublishResponse
Coordinator->NodeB: new PublishWithJoinResponse
NodeB->Master: PublishWithJoinResponse
Master -[#red]>PublishResponseHandler:onResponse()
PublishResponseHandler -> CoordinationState:handlePublishResponse()
CoordinationState->CoordinationState:publishVotes.addVote(sourceNode) 收集publish响应
alt isPublishQuorum(publishVotes) 半数
CoordinationState->CoordinationState:new ApplyCommitRequest()else
CoordinationState->CoordinationState:Optional.empty()
endalt assert applyCommitRequest.isPresent() == false
CoordinationState->PublicationTarget: forEach sendApplyCommit()
PublicationTarget->Publication:sendApplyCommit()
Master->NodeB:internal:cluster/coordination/commit_state
NodeB->Coordinator:handleApplyCommit()
Coordinator->CoordinationState:handleCommit()
CoordinationState->PersistedState:markLastAcceptedStateAsCommitted() 标记已提交
NodeB->Master: TransportResponse.Empty
Master->ApplyCommitResponseHandler:onResponse()
ApplyCommitResponseHandler->PublicationTarget:setAppliedCommit()
PublicationTarget->Publication:onPossibleCompletion()
end
@enduml