Spark Standalone架构设计要点分析

来源:互联网 发布:张子枫清华附中知乎 编辑:程序博客网 时间:2024/06/08 00:13

Apache Spark是一个开源的通用集群计算系统,它提供了High-level编程API,支持Scala、Java和Python三种编程语言。Spark内核使用Scala语言编写,通过基于Scala的函数式编程特性,在不同的计算层面进行抽象,代码设计非常优秀。

RDD抽象
RDD(Resilient Distributed Datasets),弹性分布式数据集,它是对分布式数据集的一种内存抽象,通过受限的共享内存方式来提供容错性,同时这种内存模型使得计算比传统的数据流模型要高效。
计算抽象重点内容
在描述Spark中的计算抽象,我们首先需要了解如下几个概念:
●Application
用户编写的Spark程序,完成一个计算任务的处理。它是由一个Driver程序和一组运行于Spark集群上的Executor组成。
●Job
用户程序中,每次调用Action时,逻辑上会生成一个Job,一个Job包含了多个Stage。
●Stage
Stage包括两类:ShuffleMapStage和ResultStage,如果用户程序中调用了需要进行Shuffle计算的Operator,如groupByKey等,就会以Shuffle为边界分成ShuffleMapStage和ResultStage。
●TaskSet
基于Stage可以直接映射为TaskSet,一个TaskSet封装了一次需要运算的、具有相同处理逻辑的Task,这些Task可以并行计算,粗粒度的调度是以TaskSet为单位的。
●Task
Task是在物理节点上运行的基本单位,Task包含两类:ShuffleMapTask和ResultTask,分别对应于Stage中ShuffleMapStage和ResultStage中的一个执行基本单元。
这里写图片描述
下面,我们看一下,上面这些基本概念之间的关系,如下图所示:
这里写图片描述
上图,为了简单,每个Job假设都很简单,并且只需要进行一次Shuffle处理,所以都对应2个Stage。实际应用中,一个Job可能包含若干个Stage,或者是一个相对复杂的Stage DAG。

在Standalone模式下,默认使用的是FIFO这种简单的调度策略,在进行调度的过程中,大概流程如下图所示:
这里写图片描述
从用户提交Spark程序,最终生成TaskSet,而在调度时,通过TaskSetManager来管理一个TaskSet(包含一组可在物理节点上执行的Task),这里面TaskSet必须要按照顺序执行才能保证计算结果的正确性,因为TaskSet之间是有序依赖的(上溯到ShuffleMapStage和ResultStage),只有一个TaskSet中的所有Task都运行完成后,才能调度下一个TaskSet中的Task去执行。

集群模式
Spark集群在设计的时候,并没有在资源管理的设计上对外封闭,而是充分考虑了未来对接一些更强大的资源管理系统,如YARN、Mesos等,所以Spark架构设计将资源管理单独抽象出一层,通过这种抽象能够构建一种适合企业当前技术栈的插件式资源管理模块,从而为不同的计算场景提供不同的资源分配与调度策略。Spark集群模式架构,如下图所示:
这里写图片描述
上图中,Spark集群Cluster Manager目前支持如下三种模式:

●Standalone模式
Standalone模式是Spark内部默认实现的一种集群管理模式,这种模式是通过集群中的Master来统一管理资源,而与Master进行资源请求协商的是Driver内部的StandaloneSchedulerBackend(实际上是其内部的StandaloneAppClient真正与Master通信),后面会详细说明。

●YARN模式
YARN模式下,可以将资源的管理统一交给YARN集群的ResourceManager去管理,选择这种模式,可以更大限度的适应企业内部已有的技术栈,如果企业内部已经在使用Hadoop技术构建大数据处理平台。

●Mesos模式
随着Apache Mesos的不断成熟,一些企业已经在尝试使用Mesos构建数据中心的操作系统(DCOS),Spark构建在Mesos之上,能够支持细粒度、粗粒度的资源调度策略(Mesos的优势),也可以更好地适应企业内部已有技术栈。

那么,Spark中是怎么考虑满足这一重要的设计决策的呢?也就是说,如何能够保证Spark非常容易的让第三方资源管理系统轻松地接入进来。我们深入到类设计的层面看一下,如下图类图所示:
这里写图片描述
可以看出,Task调度直接依赖SchedulerBackend,SchedulerBackend与实际资源管理模块交互实现资源请求。这里面,CoarseGrainedSchedulerBackend是Spark中与资源调度相关的最重要的抽象,它需要抽象出与TaskScheduler通信的逻辑,同时还要能够与各种不同的第三方资源管理系统无缝地交互。实际上,CoarseGrainedSchedulerBackend内部采用了一种ResourceOffer的方式来处理资源请求。

RPC网络通信抽象
Spark RPC层是基于优秀的网络通信框架Netty设计开发的,但是Spark提供了一种很好地抽象方式,将底层的通信细节屏蔽起来,而且也能够基于此来设计满足扩展性,比如,如果有其他不基于Netty的网络通信框架的新的RPC接入需求,可以很好地扩展而不影响上层的设计。RPC层设计,如下图类图所示:
这里写图片描述
任何两个Endpoint只能通过消息进行通信,可以实现一个RpcEndpoint和一个RpcEndpointRef:想要与RpcEndpoint通信,需要获取到该RpcEndpoint对应的RpcEndpointRef即可,而且管理RpcEndpoint和RpcEndpointRef创建及其通信的逻辑,统一在RpcEnv对象中管理。

启动Standalone集群
Standalone模式下,Spark集群采用了简单的Master-Slave架构模式,Master统一管理所有的Worker,这种模式很常见,我们简单地看下Spark Standalone集群启动的基本流程,如下图所示:

原创粉丝点击