任何框架与Yarn的结合,都必须遵循Yarn的开发模式。我们首先看看Yarn的几个基本元素的作用(如图4-9所示)。Client负责提交应用;ResourceManager负责将集群的资源分配给各个应用使用并跟踪这些资源(Container)的状态和监控其进度;ApplicationMaster(App Mstr)负责监控Task的运行过程;Container是资源分配和调度的基本单位,在其内部封装了内存、CPU、磁盘、网络等机器资源;NodeManager是一个个负责计算的工作结点,主要负责启动Application所需的Container,监控资源(如内存、CPU、磁盘、网络等)的使用情况并将之汇报给ResourceManager。
图4-9 Yarn的基本元素的作用
1.Yarn-Cluster模式下Spark的工作流程
在Yarn-Cluster模式中,当用户向Yarn中提交一个应用程序后,Yarn将分成两个阶段运行该应用程序:第一个阶段是把Spark的Driver作为一个ApplicationMaster在Yarn集群中先启动;第二个阶段是由ApplicationMaster创建应用程序,然后为该应用程序向ResourceMa-nager申请资源,并启动Executor来运行Task,同时监控它的整个运行过程,直到运行完成。Yarn-cluster的工作流程分为以下几个步骤(如图4-10所示)。
图4-10 Yarn-Cluster模式的运行流程图
(1)Spark Yarn Client通过ApplicationClientProtocol协议(Spark on yarn模式下各模块之间的通信协议,可以参考图4-11)向Yarn中的ResourceManager提交应用程序,其中包括ApplicationMaster程序、启动ApplicationMaster的命令以及需要在Executor中运行的程序等。
(2)ResourceManager收到请求后,与对应的NodeManager通信,为该应用程序分配第一个Container作为AppMaster(也就是ApplicationMaster)。
(3)ResourceManager要求NodeManager在这个Container中启动应用程序的Application-Master(AppMaster),其中ApplicationMaster中包含了SparkContext等的初始化。
(4)ApplicationMaster首先向ResourceManager注册,这样用户可以直接通过ResourceM-anage查看应用程序的运行状态。
(5)然后ApplicationMaster将采用轮询的方式通过RPC协议(这里的是ApplicationMas-terProtocol协议,如图4-11中所示)为各个任务申请资源,并监控它们的运行状态,直到运行结束,其中Application的请求、分配资源是通过YarnAllocationHandle来完成的。
(6)一旦ApplicationMaster申请到资源(也就是Container)后,便通过ContainerMan-agerProtocol协议与对应的NodeManager通信,要求它在获得的Container中启动启动CoarseG-rainedExecutorBackend,CoarseGrainedExecutorBackend启动后,会向ApplicationMaster中的SparkContext注册并申请Task,这一点和Standalone模式一样,只不过,SparkContext在Spark Application中初始化时,使用CoarseGrainedSchedulerBackend配合YarnClusterScheduler进行任务的调度,而YarnClusterScheduler只是对TaskSchedulerImpl的一个简单包装,增加了对Executor的等待逻辑等。
(7)ApplicationMaster中的SparkContext分配Task给CoarseGrainedExecutorBackend执行CoarseGrainedExecutorBackend运行Task并通过某个自定义的RPC协议向ApplicationMaster汇报自己的状态和进度,以让ApplicationMaster随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。
图4-11 Yarn框架下各个模块之间的通信图
(8)应用程序运行完成后,ApplicationMaster向ResourceManager申请注销并关闭自己。
2.Spark源码分析Yarn-Cluster运行模式的执行流程
在Spark的Yarn-Cluster模式中,ApplicationMaster指的是org.apache.deploy.yarn.App-licationMaster,Client指的是org.apache.deploy.yarn.Client。
(1)spark-submit提交应用后,会根据自己的附加属性选择模式。然后在SparkSubmit类的launch方法中会利用反射技术启动org.apache.spark.deploy.yarn.Client这个伴生对象。(www.xing528.com)
(2)在Client的main方法中,会调用new Client(args,sparkConf).run()方法,在Cli-ent类的run方法中会调用runApp()方法,在runApp()方法中会通过调用Client的submi-tApplication()方法提交应用。下面我们看一下Client的submitApplication()方法的实现。
(3)ApplicationMaster负责运行Spark Application的Driver程序,并且分配执行Task时的Executors。在ApplicationMaster中调用的是自己的run方法。
1)首先在ApplicationMaster伴生对象中会初始化ApplicationMaster类的对象,并调用该对象的run方法。
2)下面我们看一下ApplicationMaster类中的run()方法的具体实现。
3)下面我们继续跟踪runDriver方法的实现,在该方法内部会调用registerAM()方法向ResourceManager注册ApplicationMaster。
4)继续跟踪registerAM()方法的实现。在该方法中主要做两件事情:第一是Applica-tionMaster的注册。第二是ApplicationMaster向ResourceManager申请Container资源。
对收到的Container资源,ApplicationMaster会在其内部启动一个ExecutorRunner线程来管理Executor中运行的Task。
(4)最后Task会在Executor中运行,CoarseGrainedExecutorBackend通过Akka通信框架跟CoarseGrainedSchedulerBackend进行Task运行状况的通信,直到Job运行完成。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。