共计 13858 个字符,预计需要花费 35 分钟才能阅读完成。
Spark 的运行模式多种多样,在单机上既可以以本地模式运行,也可以以伪分布式模式运行。而当以分布式的方式运行在 Cluster 集群中时,底层的资源调度可以使用 Mesos 或者是 Hadoop Yarn,也可以使用 Spark 自带的 Standalone Deploy 模式
Spark 处于活跃的开发过程中,代码变动频繁,所以本文尽量不涉及具体的代码分析,仅从结构和流程的角度进行阐述。
运行模式列表
基本上,Spark 的运行模式取决于传递给 SparkContext 的 MASTER 环境变量的值,个别模式还需要辅助的程序接口来配合使用,目前支持的 Master 字符串及 URL 包括:
Local[N]:本地模式 使用 N 个线程
Local-cluster:伪分布式模式
Spark://:Standalone Deploy 模式,需要部署 Spark 到相关节点
Mesos://:Mesos 模式,需要部署 Spark 和 Mesos 到相关节点
Yarn-standalone:SparkContext 和任务都运行在 Yarn 集群中
Yarn-client:SparkConext 运行在本地,task 运行在 Yarn 集群中
此外还有一些用于调试的 URL
大致工作流程
总体上来说,这些运行模式都基于一个相似的工作流程,SparkContext 作为调度的总入口,在初始化过程中会分别创建 DAGScheduler 作业调度和 TaskScheduler 任务调度两极调度模块
作业调度模块是基于 Stage 的高层调度模块,它为每个 Spark Job 计算具有依赖关系的多个 Stage 任务阶段(通常根据 Shuffle 来划分 Stage),然后将每个 Stage 划分为具体的一组任务(通常会考虑数据的本地性等)以 Task Sets 的形式提交给底层的任务调度模块来具体执行
任务调度模块负责具体启动任务,监控和汇报任务运行情况
不同运行模式的主要区别就在于他们各自实现了自己特定的任务调度模块,用来实际执行计算任务
————————————– 分割线 ————————————–
Spark1.0.0 部署指南 http://www.linuxidc.com/Linux/2014-07/104304.htm
CentOS 6.2(64 位)下安装 Spark0.8.0 详细记录 http://www.linuxidc.com/Linux/2014-06/102583.htm
Spark 简介及其在 Ubuntu 下的安装使用 http://www.linuxidc.com/Linux/2013-08/88606.htm
安装 Spark 集群(在 CentOS 上) http://www.linuxidc.com/Linux/2013-08/88599.htm
Hadoop vs Spark 性能对比 http://www.linuxidc.com/Linux/2013-08/88597.htm
Spark 安装与学习 http://www.linuxidc.com/Linux/2013-08/88596.htm
Spark 并行计算模型 http://www.linuxidc.com/Linux/2012-12/76490.htm
————————————– 分割线 ————————————–
相关基本类
TaskScheduler / SchedulerBackend
为了抽象出一个公共的接口供 DAGScheduler 作业调度模块使用,所有的这些运行模式实现的任务调度模块都是基于两个 Trait:TaskScheduler 和 SchedulerBackend
理论上,TaskScheduler 的实现用于与 DAGScheduler 交互,负责任务的具体调度和运行,核心接口是 submitTasks 和 CancelTasks
SchedulerBackend 的实现用于与底层资源调度系统交互(如 mesos/YARN),配合 TaskScheduler 实现具体任务执行所需的资源分配,核心接口是 receiveOffers
这两者之间的实际交互过程取决于具体调度模式,理论上这两者的实现是成对匹配工作的,拆分成两部分,有利于相似的调度模式共享代码功能模块
TaskSchedulerImpl
TaskSchedulerImpl 实现了 TaskScheduler Trait,提供了大多数 Local 和 Cluster 调度模式的任务调度接口,此外还实现了 resourceOffers 和 statusUpdate 两个接口给 Backend 调用,用于提供调度资源和更新任务状态。另外在提交任务,更新状态等阶段调用 Backend 的 receiveOffers 函数用来发起一次任务资源调度请求
Executor
实际任务的运行,最终都由 Executor 类来执行,Executor 对每一个 Task 启动一个 TaskRunner 类,并通过 ExectorBackend 的接口返回 task 运行结果
具体实现
Local[N]
Local 本地模式使用 LocalBackend 配合 TaskSchedulerImpl
LocalBackend 响应 Scheduler 的 receiveOffers 请求,根据可用 CPU Core 的设定值 [N] 直接生成 WorkerOffer 资源返回给 Scheduler,并通过 Executor 类在线程池中依次启动和运行 Scheduler 返回的任务列表
Spark Standalone Deploy
Standalone 模式使用 SparkDeploySchedulerBackend 配合 TaskSchedulerImpl,而 SparkDeploySchedulerBackend 本身拓展自 CoarseGrainedSchedulerBackend
CoarseGrainedSchedulerBackend 是一个基于 Akka Actor 实现的粗粒度的资源调度类,在整个 SparkJob 运行期间,CoarseGrainedSchedulerBackend 会监听并持有注册给它的 Executor 资源(相对于细粒度的调度,Executor 基于每个任务的生命周期创建和销毁),并且在接受 Executor 注册,状态更新,响应 Scheduler 请求等各种时刻,根据现有 Executor 资源发起任务调度流程
Executor 本身通过各种途径启动,在 Spark Standalone 模式中,SparkDeploySchedulerBackend 通过 Client 类向 Spark Master 发送请求在独立部署的 Spark 集群中启动 CoarseGrainedExecutorBackend,根据所需的 CPU 资源 Core 的数量,一个或多个 CoarseGrainedExecutorBackend 在 Spark Worker 节点上启动并注册给 CoarseGrainedSchedulerBackend 的 DriverActor
完成所需 Actor 的启动之后,之后的任务调度就在 CoarseGrainedSchedulerBackend 和 CoarseGrainedExecutorBackend 的 Actor 之间直接完成
Local-cluster
伪分布模式基于 Standalone 模式实现,实际就是在 SparkContext 初始化的过程中现在本地启动一个单机的伪分布 Spark 集群,之后的流程与 Standalone 模式相同
Mesos
Mesos 模式根据调度的颗粒度,分别使用 CoarseMesosSchedulerBackend 和 MesosSchedulerBackend 配合 TaskSchedulerImpl
粗粒度的 CoarseMesosSchedulerBackend 拓展自 CoarseGrainedSchedulerBackend,相对于父类额外做的工作就是实现了 MScheduler 接口,注册到 Mesos 资源调度的框架中,用于接收 Mesos 的资源分配,在得到资源后通过 Mesos 框架远程启动 CoarseGrainedExecutorBackend,之后的任务交互过程和 Spark standalone 模式一样,由 DriverActor 和 Executor Actor 直接完成
细粒度的 MesosSchedulerBackend 不使用 CoarseMesosSchedulerBackend 的基于 Actor 的调度模式,因此直接继承自 SchedulerBackend,同样实现了 MScheduler 接口,注册到 Mesos 资源调度的框架中,用于接收 Mesos 的资源分配。不同的是在接收资源后,MesosSchedulerBackend 启动的是基于 Task 任务的远程 Executor,通过在远程执行 ./sbin/spark-executor 命令来启动 MesosExecutorBackend,在 MesosExecutorBackend 中直接 launch 对应的 Task
Yarn-standalone
Yarn-Standalone 模式相对其它模式有些特殊,需要由外部程序辅助启动 APP。用户的应用程序通过 org.apache.spark.deploy.yarn.Client 启动
Client 通过 Yarn Client API 在 Hadoop 集群上启动一个 Spark ApplicationMaster,Spark ApplicationMaster 首先注册自己为一个 YarnApplication Master,之后启动用户程序,SparkContext 在用户程序中初始化时,使用 CoarseGrainedSchedulerBackend 配合 YarnClusterScheduler,YarnClusterScheduler 只是对 TaskSchedulerImpl 的一个简单包装,增加对 Executor 的等待逻辑等。
然后根据 Client 传递过来的参数,SparkApplicationMaster 通过 Yarn RM/NM 的接口在集群中启动若干个 Container 用于运行 CoarseGrainedExecutorBackend 往 CoarseGrainedSchedulerBackend 注册。之后的任务调度流程同上述其它 Cluster 模式
Yarn-client
Yarn-client 模式中,SparkContext 运行在本地,该模式适用于应用 APP 本身需要在本地进行交互的场合,比如 Spark Shell,Shark 等
Yarn-client 模式下,SparkContext 在初始化过程中启动 YarnClientSchedulerBackend(同样拓展自 CoarseGrainedSchedulerBackend),该 Backend 进一步调用 org.apache.spark.deploy.yarn.Client 在远程启动一个 WorkerLauncher 作为 Spark 的 Application Master,相比 Yarn-standalone 模式,WorkerLauncher 不再负责用户程序的启动(已经在客户端本地启动),而只是启动 Container 运行 CoarseGrainedExecutorBackend 与客户端本地的 Driver 进行通讯,后续任务调度流程相同
概括
总体而言,各种运行模式就是通过各种手段启动匹配的 SchedulerBackend 和 ExecutorBackend。除了 Local 模式和细粒度的 Mesos 模式,其它模式最终都是通过基于 Akka 的 CoarseGrainedSchedulerBackend 和 CoarseGrainedExecutorBackend 完成任务调度
更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2014-10/107976p2.htm
上一篇中介绍了 Spark 的各种运行模式的基本流程和相关实现,这里主要分析一下各种运行模式中涉及到的一些细节问题的流程和实现
Spark 的各种运行模式虽然启动方式,运行位置,调度手段有所不同,但它们所要完成的任务基本都是一致的,就是在合适的位置安全可靠的根据用户的配置和 Job 的需要管理和运行 Task,这里粗略的列举一下在运行调度过程中各种需要考虑的问题
环境变量的传递
Jar 包和各种依赖文件的分发
Task 的管理和序列化等
用户参数配置
用户及权限控制
环境变量的传递
Spark 的运行参数有很大一部分是通过环境变量来设置的,例如 Executor 的内存设置,Library 路径等等。Local 模式当然不存在环境变量的传递问题,在 Cluster 模式下,就需要将环境变量传递到远端 JVM 环境中去
SparkContext 在初始化过程中 需要传递给 Executor 的环境变量,会在 executorEnvs 变量中(HashMap)中收集起来
而具体如何将这些变量设置到 Executor 的环境中,取决于 Executor 的 Launch 方式
在 Spark Standalone 模式中,这些变量被封装在 org.apache.spark.deploy.Command 中,交给 AppClient 启动远程 Executor,Command 经由 Spark Master 通过 Actor 再次转发给合适的 Worker,Worker 通过 ExecutorRunner 构建 Java.lang.Process 运行 ExecutorBackend,环境变量在 ExecutorRunner 中传递给 java.lang.ProcessBuilder.environment 完成整个传递过程
在 Mesos 相关模式中,这些环境变量被设置到 org.apache.mesos.Protos.Environment 中,在通过 MesosLaunch Task 时交给 Mesos 完成分发工作
在 yarn-standalone 模式中,这些环境变量首先要通过 Yarn Client 设置到 Spark AM 的运行环境中,基本就是 Client 类运行环境中以 SPARK 开头的环境变量全部设置到 ContainerLaunchContext 中,AM 通过 WorkerRunnable 进一步将它们设置到运行 Executor 所用的 ContainerLaunchContext 中
Yarn-client 模式与 yarn-standalone 模式大致相同,虽然 SparkContext 运行在本地,executor 所需的环境变量还是通过 ContainerLaunchContext 经 AM 中转发给 Executor
可以注意到,在 Yarn 相关模式中,并没有使用到 SparkContext 收集的 executorEnvs,主要是因为 Yarn Standalone 模式下 Sparkcontext 本身就是在远程运行的,因此在 Yarn Client 中单独实现了相关代码
Jar 包和各种依赖文件的分发
Spark 程序的运行依赖大致分两类, 一是 Spark runtime 及其依赖,二是应用程序自身的额外依赖
对于 Local 模式而言,不存在 Jar 包分发的问题
对于第一类依赖
在 Spark Standalone 模式中,整个环境随 Spark 部署到各个节点中,因此也不存在 runtime Jar 包分发的问题
Mesos 相关模式下,Mesos 本身需要部署到各个节点,SparkRuntime 可以和 Standalone 模式一样部署到各个节点中,也可以上传到 Mesos 可以读取的地方比如 HDFS 上,然后通过配置 spark.executor.uri 通知 Mesos 相关的 SchedulerBackend,它们会将该 URL 传递给 Mesos,Mesos 在 Launch 任务时会从指定位置获取相关文件
而 Spark 应用程序所额外依赖的文件,在上述模式中可以通过参数将 URL 传递给 SparkContext,对于本地文件 SparkContext 将启动一个 HttpServer 用于其它节点读取相关文件,其它如 HDFS 和外部 HTTP 等地址上的文件则原封不动,然后这些额外依赖文件的 URL 在 TaskSetmanager 中和 Task 本身一起被序列化后发送给 Executor,Executor 再反序列化得到 URL 并传递给 ExecutorURLClassLoader 使用
在 Yarn 相关模式中,Runtime 和程序运行所依赖的文件首先通过 HDFS Client API 上传到 Job 的.sparkStaging 目录下,然后将对应的文件和 URL 映射关系通过 containerLaunchContext.setLocalResources 函数通知 Yarn,Yarn 的 NodeManager 在 Launch container 的时候会从指定 URL 处下载相关文件作为运行环境的一部分。上面的步骤对于 Spark AM 来说是充分的,而对于需要进一步分发到 Executor 的运行环境中的文件来说,AM 还需要在创建 Executor 的 Container 的时候同样调用 setLocalResources 函数,AM 是如何获得对应的文件和 URL 列表的呢,其实就是 SparkYarn Client 将这些文件的相关属性如 URL,时间戳,尺寸等信息打包成字符串,通过特定的环境变量(SPARK_YARN_CACHE_XXX)传递给 AM,AM 再把它们从环境变量中还原成所需文件列表
Task 管理和序列化
Task 的运行要解决的问题不外乎就是如何以正确的顺序,有效地管理和分派任务,如何将 Task 及运行所需相关数据有效地发送到远端,以及收集运行结果
Task 的派发源起于 DAGScheduler 调用 TaskScheduler.submitTasks 将一个 Stage 相关的一组 Task 一起提交调度。
在 TaskSchedulerImpl 中,这一组 Task 被交给一个新的 TaskSetManager 实例进行管理,所有的 TaskSetManager 经由 SchedulableBuilder 根据特定的调度策略进行排序,在 TaskSchedulerImpl 的 resourceOffers 函数中,当前被选择的 TaskSetManager 的 ResourceOffer 函数被调用并返回包含了序列化任务数据的 TaskDescription,最后这些 TaskDescription 再由 SchedulerBackend 派发到 ExecutorBackend 去执行
系列化的过程中,上一节中所述 App 依赖文件相关属性 URL 等通过 DataOutPutStream 写出,而 Task 本身通过可配置的 Serializer 来序列化,当前可配制的 Serializer 包括如 JavaSerializer,KryoSerializer 等
Task 的运行结果在 Executor 端被序列化并发送回 SchedulerBackend,由于受到 Akka Frame Size 尺寸的限制,如果运行结果数据过大,结果会存储到 BlockManager 中,这时候发送到 SchedulerBackend 的是对应数据的 BlockID,TaskScheduler 最终会调用 TaskResultGetter 在线程池中以异步的方式读取结果,TaskSetManager 再根据运行结果更新任务状态(比如失败重试等)并汇报给 DAGScheduler 等
用户参数配置
Spark 的用户参数配置途径很多,除了环境变量以外,可以通过 Spark.conf 文件设置,也可以通过修改系统属性设置 “spark.*”
而这些配置参数的使用环境也很多样化,有些在 Sparkcontext 本地使用(除了 yarn-standalone 模式),有些需要分发到 Cluster 集群中去
在 SparkContext 中解析和使用,比如 spark.master,spark.app.names, spark.jars 等等,通常用于配置 SparkContext 运行参数,创建 Executor 启动环境等
发送给 Executor 的参数又分两部分
一部分在 ExecutorBackend 初始化过程中需要使用的系统变量,会通过 SparkContext 在初始化过程中读取并设置到环境变量中去,在通过前面所述的方式,使用对应的底层资源调度系统设置到运行容器的环境变量中
另一部分在 Executor 中才使用的以 ”spark.*” 开头的参数,则通过 ExecutorBackend 向 SchedulerBackend 的注册过程,在注册确认函数中传递给 ExecutorBackend 再在 Executor 的初始化过程中设置到 SparkConf 中
总体看来,这些参数配置的方式和分发途径有些不太统一,稍显混乱,大概还有改进的余地
用户及权限控制
Spark 的 Task 在 Executor 中运行时,使用 Hadoop 的 UerGroupInfomation.doAs 函数将整个 Task 的运行环境包装起来以特定的 sparkUser 的身份运行。这样做的目的主要是使得 Spark 的 task 在与 Hadoop 交互时,使用特定的用户而不是 Executor 启动时所用的用户身份,这有利于在集群中区分 Spark Cluster 的运行用户和实际使用集群的 APP 用户身份,以及 HDFS 等权限控制
用户名在 Executor 中通过 SPARK_USER 环境变量获取
对于 Local 模式来说,SPARK_USER 环境变量就是当前 JVM 环境下设定的值,当然对 Local 模式来说实际上也是不需要 doAs 的,Executor 中如果 SPARK_USER 变量未设定或者与当前用户名一致,会跳过 doAs 直接执行 task launch 相关函数
传递用户身份的问题容易解决,比较麻烦的是身份的认证,例如将 Spark 运行在通过 Kerberos 管理权限的 Hadoop 集群中,这需要完成客户端的身份认证,Security 相关秘钥或 Token 的获取,分发,更新,失效等工作,在保证效率的同时,还要确保整个过程的安全性,目前的 Spark 代码对这一方面还没有完善的实现方案,但是有一些提案和 Patch 正在进行中。
Spark 的详细介绍:请点这里
Spark 的下载地址:请点这里
Spark 的运行模式多种多样,在单机上既可以以本地模式运行,也可以以伪分布式模式运行。而当以分布式的方式运行在 Cluster 集群中时,底层的资源调度可以使用 Mesos 或者是 Hadoop Yarn,也可以使用 Spark 自带的 Standalone Deploy 模式
Spark 处于活跃的开发过程中,代码变动频繁,所以本文尽量不涉及具体的代码分析,仅从结构和流程的角度进行阐述。
运行模式列表
基本上,Spark 的运行模式取决于传递给 SparkContext 的 MASTER 环境变量的值,个别模式还需要辅助的程序接口来配合使用,目前支持的 Master 字符串及 URL 包括:
Local[N]:本地模式 使用 N 个线程
Local-cluster:伪分布式模式
Spark://:Standalone Deploy 模式,需要部署 Spark 到相关节点
Mesos://:Mesos 模式,需要部署 Spark 和 Mesos 到相关节点
Yarn-standalone:SparkContext 和任务都运行在 Yarn 集群中
Yarn-client:SparkConext 运行在本地,task 运行在 Yarn 集群中
此外还有一些用于调试的 URL
大致工作流程
总体上来说,这些运行模式都基于一个相似的工作流程,SparkContext 作为调度的总入口,在初始化过程中会分别创建 DAGScheduler 作业调度和 TaskScheduler 任务调度两极调度模块
作业调度模块是基于 Stage 的高层调度模块,它为每个 Spark Job 计算具有依赖关系的多个 Stage 任务阶段(通常根据 Shuffle 来划分 Stage),然后将每个 Stage 划分为具体的一组任务(通常会考虑数据的本地性等)以 Task Sets 的形式提交给底层的任务调度模块来具体执行
任务调度模块负责具体启动任务,监控和汇报任务运行情况
不同运行模式的主要区别就在于他们各自实现了自己特定的任务调度模块,用来实际执行计算任务
————————————– 分割线 ————————————–
Spark1.0.0 部署指南 http://www.linuxidc.com/Linux/2014-07/104304.htm
CentOS 6.2(64 位)下安装 Spark0.8.0 详细记录 http://www.linuxidc.com/Linux/2014-06/102583.htm
Spark 简介及其在 Ubuntu 下的安装使用 http://www.linuxidc.com/Linux/2013-08/88606.htm
安装 Spark 集群(在 CentOS 上) http://www.linuxidc.com/Linux/2013-08/88599.htm
Hadoop vs Spark 性能对比 http://www.linuxidc.com/Linux/2013-08/88597.htm
Spark 安装与学习 http://www.linuxidc.com/Linux/2013-08/88596.htm
Spark 并行计算模型 http://www.linuxidc.com/Linux/2012-12/76490.htm
————————————– 分割线 ————————————–
相关基本类
TaskScheduler / SchedulerBackend
为了抽象出一个公共的接口供 DAGScheduler 作业调度模块使用,所有的这些运行模式实现的任务调度模块都是基于两个 Trait:TaskScheduler 和 SchedulerBackend
理论上,TaskScheduler 的实现用于与 DAGScheduler 交互,负责任务的具体调度和运行,核心接口是 submitTasks 和 CancelTasks
SchedulerBackend 的实现用于与底层资源调度系统交互(如 mesos/YARN),配合 TaskScheduler 实现具体任务执行所需的资源分配,核心接口是 receiveOffers
这两者之间的实际交互过程取决于具体调度模式,理论上这两者的实现是成对匹配工作的,拆分成两部分,有利于相似的调度模式共享代码功能模块
TaskSchedulerImpl
TaskSchedulerImpl 实现了 TaskScheduler Trait,提供了大多数 Local 和 Cluster 调度模式的任务调度接口,此外还实现了 resourceOffers 和 statusUpdate 两个接口给 Backend 调用,用于提供调度资源和更新任务状态。另外在提交任务,更新状态等阶段调用 Backend 的 receiveOffers 函数用来发起一次任务资源调度请求
Executor
实际任务的运行,最终都由 Executor 类来执行,Executor 对每一个 Task 启动一个 TaskRunner 类,并通过 ExectorBackend 的接口返回 task 运行结果
具体实现
Local[N]
Local 本地模式使用 LocalBackend 配合 TaskSchedulerImpl
LocalBackend 响应 Scheduler 的 receiveOffers 请求,根据可用 CPU Core 的设定值 [N] 直接生成 WorkerOffer 资源返回给 Scheduler,并通过 Executor 类在线程池中依次启动和运行 Scheduler 返回的任务列表
Spark Standalone Deploy
Standalone 模式使用 SparkDeploySchedulerBackend 配合 TaskSchedulerImpl,而 SparkDeploySchedulerBackend 本身拓展自 CoarseGrainedSchedulerBackend
CoarseGrainedSchedulerBackend 是一个基于 Akka Actor 实现的粗粒度的资源调度类,在整个 SparkJob 运行期间,CoarseGrainedSchedulerBackend 会监听并持有注册给它的 Executor 资源(相对于细粒度的调度,Executor 基于每个任务的生命周期创建和销毁),并且在接受 Executor 注册,状态更新,响应 Scheduler 请求等各种时刻,根据现有 Executor 资源发起任务调度流程
Executor 本身通过各种途径启动,在 Spark Standalone 模式中,SparkDeploySchedulerBackend 通过 Client 类向 Spark Master 发送请求在独立部署的 Spark 集群中启动 CoarseGrainedExecutorBackend,根据所需的 CPU 资源 Core 的数量,一个或多个 CoarseGrainedExecutorBackend 在 Spark Worker 节点上启动并注册给 CoarseGrainedSchedulerBackend 的 DriverActor
完成所需 Actor 的启动之后,之后的任务调度就在 CoarseGrainedSchedulerBackend 和 CoarseGrainedExecutorBackend 的 Actor 之间直接完成
Local-cluster
伪分布模式基于 Standalone 模式实现,实际就是在 SparkContext 初始化的过程中现在本地启动一个单机的伪分布 Spark 集群,之后的流程与 Standalone 模式相同
Mesos
Mesos 模式根据调度的颗粒度,分别使用 CoarseMesosSchedulerBackend 和 MesosSchedulerBackend 配合 TaskSchedulerImpl
粗粒度的 CoarseMesosSchedulerBackend 拓展自 CoarseGrainedSchedulerBackend,相对于父类额外做的工作就是实现了 MScheduler 接口,注册到 Mesos 资源调度的框架中,用于接收 Mesos 的资源分配,在得到资源后通过 Mesos 框架远程启动 CoarseGrainedExecutorBackend,之后的任务交互过程和 Spark standalone 模式一样,由 DriverActor 和 Executor Actor 直接完成
细粒度的 MesosSchedulerBackend 不使用 CoarseMesosSchedulerBackend 的基于 Actor 的调度模式,因此直接继承自 SchedulerBackend,同样实现了 MScheduler 接口,注册到 Mesos 资源调度的框架中,用于接收 Mesos 的资源分配。不同的是在接收资源后,MesosSchedulerBackend 启动的是基于 Task 任务的远程 Executor,通过在远程执行 ./sbin/spark-executor 命令来启动 MesosExecutorBackend,在 MesosExecutorBackend 中直接 launch 对应的 Task
Yarn-standalone
Yarn-Standalone 模式相对其它模式有些特殊,需要由外部程序辅助启动 APP。用户的应用程序通过 org.apache.spark.deploy.yarn.Client 启动
Client 通过 Yarn Client API 在 Hadoop 集群上启动一个 Spark ApplicationMaster,Spark ApplicationMaster 首先注册自己为一个 YarnApplication Master,之后启动用户程序,SparkContext 在用户程序中初始化时,使用 CoarseGrainedSchedulerBackend 配合 YarnClusterScheduler,YarnClusterScheduler 只是对 TaskSchedulerImpl 的一个简单包装,增加对 Executor 的等待逻辑等。
然后根据 Client 传递过来的参数,SparkApplicationMaster 通过 Yarn RM/NM 的接口在集群中启动若干个 Container 用于运行 CoarseGrainedExecutorBackend 往 CoarseGrainedSchedulerBackend 注册。之后的任务调度流程同上述其它 Cluster 模式
Yarn-client
Yarn-client 模式中,SparkContext 运行在本地,该模式适用于应用 APP 本身需要在本地进行交互的场合,比如 Spark Shell,Shark 等
Yarn-client 模式下,SparkContext 在初始化过程中启动 YarnClientSchedulerBackend(同样拓展自 CoarseGrainedSchedulerBackend),该 Backend 进一步调用 org.apache.spark.deploy.yarn.Client 在远程启动一个 WorkerLauncher 作为 Spark 的 Application Master,相比 Yarn-standalone 模式,WorkerLauncher 不再负责用户程序的启动(已经在客户端本地启动),而只是启动 Container 运行 CoarseGrainedExecutorBackend 与客户端本地的 Driver 进行通讯,后续任务调度流程相同
概括
总体而言,各种运行模式就是通过各种手段启动匹配的 SchedulerBackend 和 ExecutorBackend。除了 Local 模式和细粒度的 Mesos 模式,其它模式最终都是通过基于 Akka 的 CoarseGrainedSchedulerBackend 和 CoarseGrainedExecutorBackend 完成任务调度
更多详情见请继续阅读下一页的精彩内容:http://www.linuxidc.com/Linux/2014-10/107976p2.htm