1 Spark运行时的架构

在分布式环境下,Spark 集群采用的是主/ 从结构。在一个Spark 集群中,有一个节点负责中央协调,调度各个分布式工作节点。这个中央协调节点被称为驱动器(Driver)节点,与之对应的工作节点被称为执行器(executor)节点。驱动器节点可以和大量的执行器节点进行通信,它们也都作为独立的Java 进程运行。驱动器节点和所有的执行器节点一起被称为一个Spark 应用(application)。

spark 主节点起不来 spark的从节点叫什么_spark-submit


Spark 应用通过一个叫作集群管理器(Cluster Manager)的外部服务在集群中的机器上启动。Spark 自带的集群管理器被称为独立集群管理器。Spark 也能运行在Hadoop YARN 和Apache Mesos 这两大开源集群管理器上。

1.1 驱动器节点Driver

Spark 驱动器是执行你的程序中的main() 方法的进程。它执行用户编写的用来创建
SparkContext、创建RDD,以及进行RDD 的转化操作和行动操作的代码。其实,当你启动Spark shell 时,你就启动了一个Spark 驱动器程序(Spark shell 总是会预先加载一个叫作sc的SparkContext 对象)。驱动器程序一旦终止,Spark 应用也就结束了。

驱动器程序在Spark 应用中有下述两个职责。

把用户程序转为任务

Spark 驱动器程序负责把用户程序转为多个物理执行的单元,这些单元也被称为任务
(task)。从上层来看,所有的Spark 程序都遵循同样的结构:程序从输入数据创建一系列RDD,再使用转化操作派生出新的RDD,最后使用行动操作收集或存储结果RDD
中的数据。Spark 程序其实是隐式地创建出了一个由操作组成的逻辑上的有向无环图
(Directed Acyclic Graph,简称DAG)。当驱动器程序运行时,它会把这个逻辑图转为物理执行计划。

Spark 会对逻辑执行计划作一些优化,比如将连续的映射转为流水线化执行,将多个操作合并到一个步骤中等。这样Spark 就把逻辑计划转为一系列步骤(stage)。而每个步骤又由多个任务组成。这些任务会被打包并送到集群中。任务是Spark 中最小的工作单元,用户程序通常要启动成百上千的独立任务。

为执行器节点调度任务

有了物理执行计划之后,Spark 驱动器程序必须在各执行器进程间协调任务的调度。执行器进程启动后,会向驱动器进程注册自己。因此,驱动器进程始终对应用中所有的执行器节点有完整的记录。每个执行器节点代表一个能够处理任务和存储RDD 数据的进程。

Spark 驱动器程序会根据当前的执行器节点集合,尝试把所有任务基于数据所在位置分配给合适的执行器进程。当任务执行时,执行器进程会把缓存数据存储起来,而驱动器进程同样会跟踪这些缓存数据的位置,并且利用这些位置信息来调度以后的任务,以尽量减少数据的网络传输。

驱动器程序会将一些Spark 应用的运行时的信息通过网页界面呈现出来,默认在端口
4040 上。比如,在本地模式下,访问http://localhost:4040 就可以看到这个网页了。

1.2 执行器节点Executor

Spark 执行器节点是一种工作进程,负责在Spark 作业中运行任务,任务间相互独立。Spark 应用启动时,执行器节点就被同时启动,并且始终伴随着整个Spark 应用的生命周期而存在。如果有执行器节点发生了异常或崩溃,Spark 应用也可以继续执行。执行器进程有两大作用:第一,它们负责运行组成Spark 应用的任务,并将结果返回给驱动器进程;第二,它们通过自身的块管理器(Block Manager)为用户程序中要求缓存的RDD 提供内存式存储。RDD 是直接缓存在执行器进程内的,因此任务可以在运行时充分利用缓存数据加速运算。

在本地模式下,Spark 驱动器程序和各执行器程序在同一个Java 进程中运行。这是一个特例;执行器程序通常都运行在专用的进程中。

1.3 集群管理器

Spark 依赖于集群管理器来启动执行器节点,而在某些特殊情况下,也依赖集群管理器来启动驱动器节点。集群管理器是Spark 中的可插拔式组件。这样,除了Spark 自带的独立集群管理器,Spark 也可以运行在其他外部集群管理器上,比如YARN 和Mesos。

Spark 文档中始终使用驱动器节点和执行器节点的概念来描述执行Spark应用的进程。而主节点(master)和工作节点(worker)的概念则被用来分别表述集群管理器中的中心化的部分和分布式的部分。这些概念很容易混淆,所以要格外小心。例如,Hadoop YARN 会启动一个叫作资源管理器(Resource Manager)的主节点守护进程,以及一系列叫作节点管理器(Node Manager)的工作节点守护进程。而在YARN 的工作节点上,Spark 不仅可以运行执行器进程,还可以运行驱动器进程。

1.4 启动一个程序

不论你使用的是哪一种集群管理器,你都可以使用Spark 提供的统一脚本spark-submit 将你的应用提交到那种集群管理器上。通过不同的配置选项,spark-submit 可以连接到相应的集群管理器上,并控制应用所使用的资源数量。在使用某些特定集群管理器时,sparksubmit也可以将驱动器节点运行在集群内部(比如一个YARN 的工作节点)。但对于其他的集群管理器,驱动器节点只能被运行在本地机器上。

1.5 Spark应用执行流程概述

(1) 用户通过spark-submit 脚本提交应用。

(2) spark-submit 脚本启动驱动器程序,调用用户定义的main() 方法。

(3) 驱动器程序与集群管理器通信,申请资源以启动执行器节点。

(4) 集群管理器为驱动器程序启动执行器节点。

(5) 驱动器进程执行用户应用中的操作。根据程序中所定义的对RDD 的转化操作和行动操作,驱动器节点把工作以任务的形式发送到执行器进程。

(6) 任务在执行器程序中进行计算并保存结果。

(7) 如果驱动器程序的main() 方法退出,或者调用了SparkContext.stop(),驱动器程序会终止执行器进程,并且通过集群管理器释放资源。

2 使用spark-submit部署应用

Spark 为各种集群管理器提供了统一的工具来提交作业,这个工具是sparksubmit。

bin/spark-submit my_script.py

如果在调用spark-submit 时除了脚本或JAR 包的名字之外没有别的参数,那么这个Spark程序只会在本地执行。当我们希望将应用提交到Spark 独立集群上的时候,可以将独立集群的地址和希望启动的每个执行器进程的大小作为附加标记提供

bin/spark-submit --master spark://host:7077 --executor-memory 10g my_script.py

–master 标记指定要连接的集群URL;在这个示例中,spark:// 表示集群使用独立模式

spark 主节点起不来 spark的从节点叫什么_spark-submit_02


除了集群URL,spark-submit 还提供了各种选项,可以让你控制应用每次运行的各项细节。这些选项主要分为两类。第一类是调度信息,比如你希望为作业申请的资源量。第二类是应用的运行时依赖,比如需要部署到所有工作节点上的库和文件。

spark-submit 的一般格式如下:

bin/spark-submit [options] <app jar | python file> [app options]

[options] 是要传给spark-submit 的标记列表。你可以运行spark-submit --help 列出所有可以接收的标记。表7-2 列出了一些常见的标记。

<app jar | python file> 表示包含应用入口的JAR 包或Python 脚本。

[app options] 是传给你的应用的选项。如果你的程序要处理传给main() 方法的参数,它只会得到[app options] 对应的标记,不会得到spark-submit 的标记。

spark 主节点起不来 spark的从节点叫什么_Spark Driver_03

下面展示了一些使用各种选项调用spark-submit 的例子,这些调用语句都比较长。

# 使用独立集群模式提交Java应用
$ ./bin/spark-submit \
--master spark://hostname:7077 \
--deploy-mode cluster \
--class com.databricks.examples.SparkExample \
--name "Example Program" \
--jars dep1.jar,dep2.jar,dep3.jar \
--total-executor-cores 300 \
--executor-memory 10g \
myApp.jar "options" "to your application" "go here"

# 使用YARN客户端模式提交Python应用
$ export HADOOP_CONF_DIR=/opt/hadoop/conf
$ ./bin/spark-submit \
--master yarn \
--py-files somelib-1.2.egg,otherlib-4.4.zip,other-file.py \
--deploy-mode client \
--name "Example Program" \
--queue exampleQueue \
--num-executors 40 \
--executor-memory 10g \
my_script.py "options" "to your application" "go here"

参考 《Spark快速大数据分析》