Flink源码解析(二)JobManager启动分析

1、Flink主节点JobManager启动分析:

1、JobManager是Flink集群的主节点,它包含三大重要的组件:

  • ResourceManager
    • Flink的集群资源管理器,只有一个,关于slot的管理和申请等工作,都由他负责
  • Dispatcher
    • 负责接收用户提交的JobGraph,然后启动一个JobManager,类似于YARN集群中的AppMster角色,类似于Spark Job中的Driver角色。启动的时候还会恢复被中断的任务。
  • JobManager
    • 负责一个具体的Job的执行,在一个集群中,可以会有多个JobManager同时执行,类似于YARN集群中的AppMaster角色,类似于Spark Job中的Driver角色
  • WebMonitorEndpoint
    • 里面维护了很多很多的Handler,如果客户端通过flink run的方式来提交一个job到flink集群,最终由WebMonitorEndpoint来接收,并且决定使用哪一个Handler来执行处理。(submitJob--> SubmitJobHandler)

总结:

        Flink集群的主节点内部运行着:ResourceManager和Dispatcher,当client提交一个job到集群运行的时候(客户端会把该Job构建成一个JobGragh对象),Dispatcher负责拉起JobManager来负责这个Job内部的Task的执行,执行Task所需要的资源,JobManager向ResourceManager申请。

2、源码分析

        由上一篇我们知道,JobManager的启动类为StandaloneSessionClusterEntrypoint。这里,我们主要看其核心代码:

StandaloneSessionClusterEntrypoint.main()

ClusterEntrypoint.runClusterEntrypoint(entrypoint)

clusterEntrypoint.startCluster()

runCluster(configuration, pluginManager)        

         可以看到启动的核心主要在ClusterEntrypoint类中的runCluster方法:

/*************************************************
 *  注释:这个方法主要是做两件事情:
 *  1、initializeServices() 初始化相关服务
 *  2、dispatcherResourceManagerComponentFactory.create() 启动 Dispatcher 和 ResourceManager 服务。
 ****/
private void runCluster(Configuration configuration, PluginManager pluginManager) throws Exception {
	synchronized(lock) {

		/**
		 *  注释: 初始化服务,如 JobManager 的 Akka RPC 服务,HA 服务,心跳检查服务,metric service
		 *  这些服务都是 Master 节点要使用到的一些服务
		 *  1、commonRpcService: 	基于 Akka 的 RpcService 实现。RPC 服务启动 Akka 参与者来接收从 RpcGateway 调用 RPC
         *  2、初始化一个 ioExecutor
		 *  3、haServices: 			提供对高可用性所需的所有服务的访问注册,分布式计数器和领导人选举
		 *  4、blobServer: 			负责侦听传入的请求生成线程来处理这些请求。它还负责创建要存储的目录结构 blob 或临时缓存它们
		 *  5、heartbeatServices: 	提供心跳所需的所有服务。这包括创建心跳接收器和心跳发送者。
		 *  6、metricRegistry:  	跟踪所有已注册的 Metric,它作为连接 MetricGroup 和 MetricReporter
		 *  7、archivedExecutionGraphStore:  	存储执行图ExecutionGraph的可序列化形式。
		 */
		initializeServices(configuration, pluginManager);

		// TODO:将 jobmanager 地址写入配置
		// write host information into configuration
		configuration.setString(JobManagerOptions.ADDRESS, commonRpcService.getAddress());
		configuration.setInteger(JobManagerOptions.PORT, commonRpcService.getPort());

		/*************************************************
		 *  注释: 初始化一个 DefaultDispatcherResourceManagerComponentFactory 工厂实例
		 *  内部初始化了三大工厂实例
		 *  1、DispatcherRunnerFactory = DefaultDispatcherRunnerFactory
		 *  2、ResourceManagerFactory = StandaloneResourceManagerFactory
		 *  3、RestEndpointFactory(WenMonitorEndpoint的工厂) = SessionRestEndpointFactory
		 *  返回值:DefaultDispatcherResourceManagerComponentFactory
		 *  内部包含了这三个工厂实例,就是三个成员变量
		 *	-
		 *  再补充一个:dispatcherLeaderProcessFactoryFactory = SessionDispatcherLeaderProcessFactoryFactory
		 */
		final DispatcherResourceManagerComponentFactory dispatcherResourceManagerComponentFactory =
			createDispatcherResourceManagerComponentFactory(configuration);

		/*************************************************
		 *   注释:启动关键组件:Dispatcher 和 ResourceManager。
		 *   1、Dispatcher: 负责用于接收作业提交,持久化它们,生成要执行的作业管理器任务,并在主任务失败时恢复它们。
		 *   				此外, 它知道关于 Flink 会话集群的状态。负责为这个新提交的作业拉起一个新的 JobManager 服务
		 *   2、ResourceManager: 负责资源的分配和记帐。在整个 Flink 集群中只有一个 ResourceManager,资源相关的内容都由这个服务负责
		 *   				registerJobManager(JobMasterId, ResourceID, String, JobID, Time) 负责注册 jobmaster,
		 *                  requestSlot(JobMasterId, SlotRequest, Time) 从资源管理器请求一个槽
		 *   3、WebMonitorEndpoint: 服务于 web 前端 Rest 调用的 Rest 端点,用于接收客户端发送的执行任务的请求
		 */
		clusterComponent = dispatcherResourceManagerComponentFactory
			.create(configuration, ioExecutor, commonRpcService, haServices,
				blobServer, heartbeatServices, metricRegistry,
				archivedExecutionGraphStore,
				new RpcMetricQueryServiceRetriever(metricRegistry.getMetricQueryServiceRpcService()),
				this);

		/*************************************************
		 *  注释:集群关闭时的回调
		 */
		clusterComponent.getShutDownFuture().whenComplete((ApplicationStatus applicationStatus, Throwable throwable) -> {
			if(throwable != null) {
				shutDownAsync(ApplicationStatus.UNKNOWN, ExceptionUtils.stringifyException(throwable), false);
			} else {
				// This is the general shutdown path. If a separate more specific shutdown was
				// already triggered, this will do nothing
				shutDownAsync(applicationStatus, null, true);
			}
		});
	}
}

2.1、初始化服务:initializeServices(configuration, pluginManager);

        在这里做了7件初始化服务的事:

	/*************************************************
	 *  注释: 初始化各种服务组件
	 */
	protected void initializeServices(Configuration configuration, PluginManager pluginManager) throws Exception {

		LOG.info("Initializing cluster services.");

		synchronized(lock) {

			/*************************************************
			 *  注释: 第一步
			 *  创建一个 Akka rpc 服务 commonRpcService: 基于 Akka 的 RpcService 实现。
			 *  RPC 服务启动 Akka 参与者来接收从 RpcGateway 调用 RPC
			 *  commonRpcService 其实是一个基于 akka 得 actorSystem,其实就是一个 tcp 的 rpc 服务,端口为:6123
			 *  1、初始化 ActorSystem
			 *  2、启动 Actor
			 */
			commonRpcService = AkkaRpcServiceUtils
				.createRemoteRpcService(configuration, configuration.getString(JobManagerOptions.ADDRESS), getRPCPortRange(configuration),
					configuration.getString(JobManagerOptions.BIND_HOST), configuration.getOptional(JobManagerOptions.RPC_BIND_PORT));

			// TODO 注释: 设置 host 和 port
			// update the configuration used to create the high availability services
			configuration.setString(JobManagerOptions.ADDRESS, commonRpcService.getAddress());
			configuration.setInteger(JobManagerOptions.PORT, commonRpcService.getPort());

			/*************************************************
			 *  注释: 第二步
			 *  初始化一个 ioExecutor
			 *  如果你当前节点有 32 个 cpu ,那么当前这个 ioExecutor 启动的线程的数量为 : 128
			 *  专门负责做IO
			 */
			ioExecutor = Executors.newFixedThreadPool(ClusterEntrypointUtils.getPoolSize(configuration), new ExecutorThreadFactory("cluster-io"));

			/*************************************************
			 *  注释: 第三步
			 *  HA service 相关的实现,它的作用有很多,到底使用哪种根据用户的需求来定义
			 *  比如:处理 ResourceManager 的 leader 选举、JobManager leader 的选举等;
			 *  haServices = ZooKeeperHaServices
			 */
			haServices = createHaServices(configuration, ioExecutor);

			/*************************************************
			 *  注释: 第四步: 初始化一个 BlobServer
			 *  主要管理一些大文件的上传等,比如用户作业的 jar 包、TM 上传 log 文件等
			 *  Blob 是指二进制大对象也就是英文 Binary Large Object 的缩写
			 */
			blobServer = new BlobServer(configuration, haServices.createBlobStore());
			blobServer.start();

			/*************************************************
			 *  注释: 第五步
			 *  初始化一个心跳服务
			 *  在主节点中,其实有很多角色都有心跳服务。 那些这些角色的心跳服务,都是在这个 heartbeatServices 的基础之上创建的
			 *  这才是真正的 心跳服务的 提供者。
			 *  谁需要心跳服务,通过 heartbeatServices 去提供一个实例 HeartBeatImpl,用来完成心跳
			 */
			heartbeatServices = createHeartbeatServices(configuration);

			/*************************************************
			 *  注释: 第六步: metrics(性能监控) 相关的服务
			 *  1、metricQueryServiceRpcService 也是一个 ActorySystem
			 *  2、用来跟踪所有已注册的Metric
			 */
			metricRegistry = createMetricRegistry(configuration, pluginManager);
			final RpcService metricQueryServiceRpcService = MetricUtils.startRemoteMetricsRpcService(configuration, commonRpcService.getAddress());
			metricRegistry.startQueryService(metricQueryServiceRpcService, null);
			final String hostname = RpcUtils.getHostname(commonRpcService);
			processMetricGroup = MetricUtils
				.instantiateProcessMetricGroup(metricRegistry, hostname, ConfigurationUtils.getSystemResourceMetricsProbingInterval(configuration));

			/*************************************************
			 *  注释: 第七步: ArchivedExecutionGraphStore: 存储 execution graph 的服务, 默认有两种实现,
			 *  1、MemoryArchivedExecutionGraphStore 主要是在内存中缓存,
			 *  2、FileArchivedExecutionGraphStore 会持久化到文件系统,也会在内存中缓存。
			 * 	这些服务都会在前面第二步创建 DispatcherResourceManagerComponent 对象时使用到。
			 * 	默认实现是基于 File 的
			 */
			archivedExecutionGraphStore = createSerializableExecutionGraphStore(configuration, commonRpcService.getScheduledExecutor());
		}
	}

2.2、初始化三个工厂实例:createDispatcherResourceManagerComponentFactory(configuration)

        初始化一个 DefaultDispatcherResourceManagerComponentFactory工厂实例,内部初始化了三个工厂实例:

  1. DispatcherRunnerFactory = DefaultDispatcherRunnerFactory
  2. ResourceManagerFactory = StandaloneResourceManagerFactory
  3. RestEndpointFactory(WebMonitorEndpoint的工厂) = SessionRestEndpointFactory

        可查看DefaultDispatcherResourceManagerComponentFactory的构造方法

public DefaultDispatcherResourceManagerComponentFactory(
		@Nonnull DispatcherRunnerFactory dispatcherRunnerFactory,
		@Nonnull ResourceManagerFactory resourceManagerFactory,
		@Nonnull RestEndpointFactory restEndpointFactory) {

		// TODO 注释: dispatcherRunnerFactory = DefaultDispatcherRunnerFactory
		this.dispatcherRunnerFactory = dispatcherRunnerFactory;

		// TODO 注释: resourceManagerFactory = StandaloneResourceManagerFactory
		this.resourceManagerFactory = resourceManagerFactory;

		// TODO 注释: restEndpointFactory = SessionRestEndpointFactory
		this.restEndpointFactory = restEndpointFactory;
	}

2.3、启动关键组件:Dispatcher和ResourceManager:dispatcherResourceManagerComponentFactory .create()

// TODO 注释: 用于 Dispatcher leader 选举
// TODO 注释: dispatcherLeaderRetrievalService = ZooKeeperLeaderRetrievalService
dispatcherLeaderRetrievalService = highAvailabilityServices.getDispatcherLeaderRetriever();

// TODO 注释: 用于 ResourceManager leader 选举
// TODO 注释: resourceManagerRetrievalService = ZooKeeperLeaderRetrievalService
resourceManagerRetrievalService = highAvailabilityServices.getResourceManagerLeaderRetriever();

// TODO 注释: Dispatcher 的 Gateway
final LeaderGatewayRetriever dispatcherGatewayRetriever = new RpcGatewayRetriever<>(rpcService,
	DispatcherGateway.class, DispatcherId::fromUuid, 10, Time.milliseconds(50L));
// TODO 注释: ResourceManager 的 Gateway
final LeaderGatewayRetriever resourceManagerGatewayRetriever = new RpcGatewayRetriever<>(rpcService,
	ResourceManagerGateway.class, ResourceManagerId::fromUuid, 10, Time.milliseconds(50L));

// TODO 注释: 创建线程池,用于执行 WebMonitorEndpoint 所接收到的 client 发送过来的请求
final ScheduledExecutorService executor = WebMonitorEndpoint
	.createExecutorService(configuration.getInteger(RestOptions.SERVER_NUM_THREADS),
		configuration.getInteger(RestOptions.SERVER_THREAD_PRIORITY), "DispatcherRestEndpoint");

// TODO 注释: 初始化 MetricFetcher
final long updateInterval = configuration.getLong(MetricOptions.METRIC_FETCHER_UPDATE_INTERVAL);
final MetricFetcher metricFetcher = updateInterval == 0 ? VoidMetricFetcher.INSTANCE : MetricFetcherImpl
	.fromConfiguration(configuration, metricQueryServiceRetriever, dispatcherGatewayRetriever, executor);

/*************************************************
 * 创建三个实例之一:
 *  注释: 创建 WebMonitorEndpoint 实例, 在 Standalone模式下:DispatcherRestEndpoint
 *  1、restEndpointFactory = SessionRestEndpointFactory
 *  2、webMonitorEndpoint = DispatcherRestEndpoint
 *  3、highAvailabilityServices.getClusterRestEndpointLeaderElectionService() = ZooKeeperLeaderElectionService
 */
webMonitorEndpoint = restEndpointFactory
	.createRestEndpoint(configuration, dispatcherGatewayRetriever, resourceManagerGatewayRetriever, blobServer, executor, metricFetcher,
		highAvailabilityServices.getClusterRestEndpointLeaderElectionService(), fatalErrorHandler);

/*************************************************
 *  注释: 启动 DispatcherRestEndpoint
 *  1、启动 Netty 服务端
 *  2、选举
 *  3、启动定时任务 ExecutionGraphCacheCleanupTask
 */
log.debug("Starting Dispatcher REST endpoint.");
webMonitorEndpoint.start();

final String hostname = RpcUtils.getHostname(rpcService);

/*************************************************
 *  注释: 2.创建 StandaloneResourceManager 实例对象  
 *  1、resourceManager = StandaloneResourceManager
 *  2、resourceManagerFactory = StandaloneResourceManagerFactory
 */
resourceManager = resourceManagerFactory
	.createResourceManager(configuration, ResourceID.generate(), rpcService, highAvailabilityServices, heartbeatServices,
		fatalErrorHandler, new ClusterInformation(hostname, blobServer.getPort()), webMonitorEndpoint.getRestBaseUrl(), metricRegistry,
		hostname);

final HistoryServerArchivist historyServerArchivist = HistoryServerArchivist
	.createHistoryServerArchivist(configuration, webMonitorEndpoint, ioExecutor);

final PartialDispatcherServices partialDispatcherServices = new PartialDispatcherServices(configuration, highAvailabilityServices,
	resourceManagerGatewayRetriever, blobServer, heartbeatServices,
	() -> MetricUtils.instantiateJobManagerMetricGroup(metricRegistry, hostname), archivedExecutionGraphStore, fatalErrorHandler,
	historyServerArchivist, metricRegistry.getMetricQueryServiceGatewayRpcAddress());

/*************************************************
 *  注释: 3.创建 并启动 Dispatcher
 *  1、dispatcherRunner = DispatcherRunnerLeaderElectionLifecycleManager
 *  2、dispatcherRunnerFactory = DefaultDispatcherRunnerFactory
 *  第一个参数: ZooKeeperLeaderElectionService
 *  -
 *  老版本: 这个地方是直接创建一个 Dispatcher 对象然后调用 dispatcher.start() 来启动
 *  新版本: 直接创建一个 DispatcherRunner, 内部就是要创建和启动 Dispatcher
 */
log.debug("Starting Dispatcher.");
dispatcherRunner = dispatcherRunnerFactory
	.createDispatcherRunner(highAvailabilityServices.getDispatcherLeaderElectionService(), fatalErrorHandler,

		// TODO 注释: 注意第三个参数
		new HaServicesJobGraphStoreFactory(highAvailabilityServices), ioExecutor, rpcService, partialDispatcherServices);

/*************************************************
 *  注释: resourceManager 启动
 */
log.debug("Starting ResourceManager.");
resourceManager.start();

/*************************************************
 *  注释: resourceManagerRetrievalService 启动
 */
resourceManagerRetrievalService.start(resourceManagerGatewayRetriever);

/*************************************************
 *  注释: ZooKeeperHaServices 启动
 */
dispatcherLeaderRetrievalService.start(dispatcherGatewayRetriever);

/*************************************************
 *  注释: 构建 DispatcherResourceManagerComponent
 */
return new DispatcherResourceManagerComponent(dispatcherRunner, resourceManager, dispatcherLeaderRetrievalService,
	resourceManagerRetrievalService, webMonitorEndpoint);

2.3.1、创建和启动webMonitorEndpoint流程

  1. restEndpointFactory.createRestEndpoint()
  2. webMonitorEndpoint.start()
    1. handlers = initializeHandlers(restAddressFuture); 初始化各种Handler,包括JobSubmitHandler
    2. state = State.RUNNING;启动Netty服务端,用于接收客户端提交的应用程序
    3. startInternal();启动的时候会进行选举,通过选举来触发服务的启动。
      1. leaderElectionService.start(this); 
        参与选举的某个获胜的角色会调用: leaderElectionService.isLeader() ==> leaderContender.grantLeaderShip() ==>进一步调用WebMonitorEndpoint的grantLeadership方法。对于其它组件的也类似。
        参与选举的某个失败的角色会调用: leaderElectionService.notLeader()
      2. startExecutionGraphCacheCleanupTask();开启定时任务,定期清理过期了的executionGraph
/*************************************************
 *  注释: 注意这个方法,因为当前这个类是 LeaderLatchListener 的子类,所以当该组件在进行选举如果成功的话
 *  则会自动调用 isLeader() 方法,否则调用 notLeader 方法。
 *  这是 ZooKeeper 的 API 框架 cruator 的机制
 */
@Override
public void start(LeaderContender contender) throws Exception {
	Preconditions.checkNotNull(contender, "Contender must not be null.");
	Preconditions.checkState(leaderContender == null, "Contender was already set.");

	LOG.info("Starting ZooKeeperLeaderElectionService {}.", this);

	synchronized(lock) {

		client.getUnhandledErrorListenable().addListener(this);

		// TODO 注释: 这个值到底是什么,根据情况而定
		leaderContender = contender;

		/*************************************************
		 *  注释: Flink的选举,和 HBase 一样都是通过 ZooKeeper 的 API 框架 Curator 实现的
		 *  1、leaderLatch.start(); 事实上就是举行选举
		 *  2、当选举结束的时候:
		 *  	如果成功了: isLeader()
		 *      如果失败了: notLeader()
		 */
		leaderLatch.addListener(this);
		leaderLatch.start();

		/*************************************************
		 *  注释: 注册监听器,如果选举结束之后:
		 *  1、自己成为 Leader, 则会回调 isLeader() 进行处理
		 *  2、自己成为 Follower,则会回调 notLeader() 进行处理
		 */
		cache.getListenable().addListener(this);
		cache.start();

		client.getConnectionStateListenable().addListener(listener);

		running = true;
	}
}

2.3.2、创建和启动StandaloneResourceManager流程

        前提:当Actor被ActorSystem创建的时候,例如,workerActorSystem.actorOf(Props[MyNodeManager], "WorkerActor"),会直接先调用其构造方法,后调用preStart()方法。

Flink源码解析(二)JobManager启动分析_第1张图片

       如上图所示,当执行resourceManagerFactory.createResourceManager(...)方法时,最终会通过RpcEndpoint的构造方法来创建。如下所示:

protected RpcEndpoint(final RpcService rpcService, final String endpointId) {
	this.rpcService = checkNotNull(rpcService, "rpcService");
	this.endpointId = checkNotNull(endpointId, "endpointId");

	/*************************************************
	 *  注释: 启动 ResourceManager 的 RPCServer 服务
	 *  这里启动的是 ResourceManager 的 Rpc 服务端。
	 *  接收 TaskManager启动好了而之后, 进行注册和心跳,来汇报 Taskmanagaer 的资源情况
	 *  通过动态代理的形式构建了一个Server
	 */
	this.rpcServer = rpcService.startServer(this);

	this.mainThreadExecutor = new MainThreadExecutor(rpcServer, this::validateRunsInMainThread);
}

        当在DefaultDispatcherResourceManagerComponentFactory中执行resourceManager.start()时会调用ResourceManager中的onStart()方法,先进行ResourceManager的选举,一样的是通过ZookeeperLeaderElectionService的start(...)来执行。选举成功后,然后调用其isLeader()方法来执行子类的grantLeadership()方法。更多可查看以下代码:

@Override
public void grantLeadership(final UUID newLeaderSessionID) {

	/*************************************************
	 *  注释: 调用: tryAcceptLeadership 方法
	 */
	final CompletableFuture acceptLeadershipFuture = clearStateFuture
		.thenComposeAsync((ignored) -> tryAcceptLeadership(newLeaderSessionID), getUnfencedMainThreadExecutor());

	// TODO 注释: 调用 confirmLeadership
	final CompletableFuture confirmationFuture = acceptLeadershipFuture.thenAcceptAsync((acceptLeadership) -> {
		if(acceptLeadership) {
			// confirming the leader session ID might be blocking,
			leaderElectionService.confirmLeadership(newLeaderSessionID, getAddress());
		}
	}, getRpcService().getExecutor());

	// TODO 注释: 调用 whenComplete
	confirmationFuture.whenComplete((Void ignored, Throwable throwable) -> {
		if(throwable != null) {
			onFatalError(ExceptionUtils.stripCompletionException(throwable));
	}
	});
}

private CompletableFuture tryAcceptLeadership(final UUID newLeaderSessionID) {

	// TODO 注释: 判断,如果集群有了 LeaderResourceManager
	if(leaderElectionService.hasLeadership(newLeaderSessionID)) {

		// TODO 注释: 申城一个 ResourceManagerID
		final ResourceManagerId newResourceManagerId = ResourceManagerId.fromUuid(newLeaderSessionID);

		log.info("ResourceManager {} was granted leadership with fencing token {}", getAddress(), newResourceManagerId);

		// TODO 注释: 如果之前已成为过 Leader 的话,则清理之前的状态
		// clear the state if we've been the leader before
		if(getFencingToken() != null) {
			clearStateInternal();
		}
		setFencingToken(newResourceManagerId);

		/*************************************************
		 *  注释: 启动服务
		 *  1、启动心跳服务
		 *  	启动两个定时任务
		 *  2、启动 SlotManager 服务
		 *  	启动两个定时任务
		 */
		startServicesOnLeadership();

		return prepareLeadershipAsync().thenApply(ignored -> true);
	} else {
		return CompletableFuture.completedFuture(false);
	}
}

        其中的startServicesOnLeadership()方法来启动2个心跳服务以及启动2个SlotManager服务。查看

1.启动心跳服务代码如下:

/*************************************************
 *  注释: 当前 ResourceManager  启动了两个心跳服务:
 *  1、taskManagerHeartbeatManager 这个心跳管理器 关心点的是: taskManager 的死活
 *  2、jobManagerHeartbeatManager 这个心跳管理器 关心点的是: jobManager 的死活
 *  taskManager 集群的资源提供者,任务执行者,从节点
 *  jobManager 每一个job会启动的一个主控程序
 *  不管是集群的从节点执行心跳,还是每一个job会启动的一个主控程序 都是向 ResourceManager 去汇报
 */
private void startHeartbeatServices() {

	/*************************************************
	 *  注释: 用来收听: TaskManager 的心跳
	 */
	taskManagerHeartbeatManager = heartbeatServices.createHeartbeatManagerSender(resourceId, new TaskManagerHeartbeatListener(), getMainThreadExecutor(), log);

	/*************************************************
	 *  注释: 用来收听: JobManager 的心跳
	 */
	jobManagerHeartbeatManager = heartbeatServices.createHeartbeatManagerSender(resourceId, new JobManagerHeartbeatListener(), getMainThreadExecutor(), log);
}

区分概念:

1.taskManager:集群的资源提供者,任务执行者,从节点

2.jobManager:每一个job会启动的一个主控程序

主节点:StandaloneSessionClusterEntrypoint
从节点:TaskManager

管理心跳:
主节点管理资源:ResourceManager
从节点管理资源: TaskExecutor 

2.开启的2个定时任务:

  • 开启第一个定时任务:checkTaskManagerTimeouts,检查TaskManager的心跳  时间间隔30s

  • 开启第二个定时任务:checkSlotRequestTimeouts,检查SplotRequest超时处理   时间间隔5分钟。jobManager申请资源超过5分钟,进行处理。

resourceManager的start方法

        这里只是发送START消息,意味着resourceManager启动好了。

rpcEndpoint.tell(ControlMessages.START, ActorRef.noSender());

2.3.3、创建并启动Dispatcher

1、重要的查看下面的调用选举方法:前面2个调用选举方法传入的是this,这里传入的dispatcherRunner。同样的,在执行完start()方法后,会执行isLeader()方法。

private DispatcherRunnerLeaderElectionLifecycleManager(T dispatcherRunner, LeaderElectionService leaderElectionService) throws Exception {
	this.dispatcherRunner = dispatcherRunner;
	this.leaderElectionService = leaderElectionService;

	/*************************************************
	 *  注释: 启动选举
	 *  参数:dispatcherRunner = DefaultDispatcherRunner
	 *  调用对象:leaderElectionService = ZooKeeperLeaderElectionService
	 *  这个选举服务对象  leaderElectionService 内部的 leaderContender 是 : DefaultDispatcherRunner
	 */
	leaderElectionService.start(dispatcherRunner);
	// leaderElectionService.start(this);
}

2.当上述选举成功后,会进入到DefaultDispatcherRunner

Flink源码解析(二)JobManager启动分析_第2张图片

 在这里开启Dispatcher服务。

public void grantLeadership(UUID leaderSessionID) {

	/*************************************************
	 *  注释: 开启 Dispatcher 服务
	 */
	runActionIfRunning(() -> startNewDispatcherLeaderProcess(leaderSessionID));
}

后续流程:

DefaultDispatcherRunner.startNewDispatcherLeaderProcess(...)
AbstractDispatcherLeaderProcess.start(...)
AbstractDispatcherLeaderProcess.startInternal(...)
SessionDispatcherLeaderProcess.onStart(...)

 SessionDispatcherLeaderProcess.onStart(...)如下:

@Override
protected void onStart() {

	/*************************************************
	 * TODO  注释: 开启服务: 启动 JobGraghStore
	 *  一个用来存储 JobGragh 的存储组件
	 */
	startServices();

	// TODO 注释: 到现在为止,依然还没有启动 Dispatcher
	onGoingRecoveryOperation = recoverJobsAsync()

		/*************************************************
		 * TODO 运行: createDispatcherIfRunning()
		 */
		.thenAccept(this::createDispatcherIfRunning)
		.handle(this::onErrorIfRunning);
}

接上面:createDispatcherIfRunning

SessionDispatcherLeaderProcess.createDispatcherIfRunning(...)
SessionDispatcherLeaderProcess.createDispatcher(...)
DefaultDispatcherGatewayServiceFactory.create(...)  在这里创建和启动dispatcher()

@Override
public AbstractDispatcherLeaderProcess.DispatcherGatewayService create(DispatcherId fencingToken, Collection recoveredJobs,
	JobGraphWriter jobGraphWriter) {

	// TODO 注释: Dispatcher 的一个默认引导程序
	// TODO 注释: 待恢复执行的 job 的集合
	final DispatcherBootstrap bootstrap = new DefaultDispatcherBootstrap(recoveredJobs);

	final Dispatcher dispatcher;
	try {

		/*************************************************
		 * TODO 注释: 创建 Dispatcher
		 *  dispatcherFactory = SessionDispatcherFactory
		 */
		dispatcher = dispatcherFactory.createDispatcher(rpcService, fencingToken, bootstrap,

			// TODO 注释: PartialDispatcherServicesWithJobGraphStore
			PartialDispatcherServicesWithJobGraphStore.from(partialDispatcherServices, jobGraphWriter));

	} catch(Exception e) {
		throw new FlinkRuntimeException("Could not create the Dispatcher rpc endpoint.", e);
	}

	/*************************************************
	 * TODO 注释: Dispatcher 也是一个 RpcEndpoint 启动起来了之后,给自己发送一个 Hello 消息证明启动
	 */
	dispatcher.start();


	// TODO 注释: 返回一个返回值
	return DefaultDispatcherGatewayService.from(dispatcher);
}

        当执行dispatcher.start()方法时,会调用内部的onStart()方法。在这里,启动Dispatcher服务和引导程序初始化,把所有中断的job恢复执行。

完整图如下:

 

你可能感兴趣的:(#,Flink源码解析)