Spark部署模式与作业提交
一、作业提交
1.1 spark-submit
Spark 所有模式均使用 spark-submit 命令提交作业,其格式如下:
./bin/spark-submit \--class <main-class> \ # 应用程序主入口类--master <master-url> \ # 集群的 Master Url 指定任务提交到哪个资源调度器--deploy-mode <deploy-mode> \ # 部署模式--conf <key>=<value> \ # 可选配置--driver-memory <> \ # 指定Driver内存大小,默认1G.工作中一般设置为5-10G--executor-memory <> \ # 指定每个executor内存大小--executor-cores <> \ # 指定每个executor的核数--total-executor-cores <> \ # 指定所有exector的总核数 [仅限于standalone模式使用]--num-executors <> \ # 指定exector个数 [仅限于yarn模式使用]--queue <> \ # 指定任务提交到哪个资源队列中 [仅限yarn模式使用]<application-jar> \ # Jar 包路径[application-arguments] #传递给主入口类的参数
需要注意的是:在集群环境下,application-jar 必须能被集群中所有节点都能访问,可以是 HDFS 上的路径;也可以是本地文件系统路径,如果是本地文件系统路径,则要求集群中每一个机器节点上的相同路径都存在该 Jar 包。
1.2 deploy-mode
deploy-mode 有 cluster 和 client 两个可选参数,默认为 client。这里以 Spark On Yarn 模式对两者进行说明 :
- 在 cluster 模式下,Spark Drvier 在应用程序的 Master 进程内运行,该进程由群集上的 YARN 管理,提交作业的客户端可以在启动应用程序后关闭;
- 在 client 模式下,Spark Drvier 在提交作业的客户端进程中运行,Master 进程仅用于从 YARN 请求资源。
1.3 master-url
master-url 的所有可选参数如下表所示:
| Master URL | Meaning |
|---|---|
local |
使用一个线程本地运行 Spark |
local[K] |
使用 K 个 worker 线程本地运行 Spark |
local[K,F] |
使用 K 个 worker 线程本地运行 , 第二个参数为 Task 的失败重试次数 |
local[*] |
使用与 CPU 核心数一样的线程数在本地运行 Spark |
local[*,F] |
使用与 CPU 核心数一样的线程数在本地运行 Spark 第二个参数为 Task 的失败重试次数 |
spark://HOST:PORT |
连接至指定的 standalone 集群的 master 节点。端口号默认是 7077。 |
spark://HOST1:PORT1,HOST2:PORT2 |
如果 standalone 集群采用 Zookeeper 实现高可用,则必须包含由 zookeeper 设置的所有 master 主机地址。 |
mesos://HOST:PORT |
连接至给定的 Mesos 集群。端口默认是 5050。对于使用了 ZooKeeper 的 Mesos cluster 来说,使用 mesos://zk://...来指定地址,使用 --deploy-mode cluster模式来提交。 |
yarn |
连接至一个 YARN 集群,集群由配置的 HADOOP_CONF_DIR或者 YARN_CONF_DIR来决定。使用 --deploy-mode参数来配置 client或 cluster模式。 |
下面主要介绍三种常用部署模式及对应的作业提交方式。
二、Local模式
Local模式就是运行在一台计算机的模式,通常就是用于在本机上练手和测试。
Local 模式下提交作业最为简单,不需要进行任何配置,提交命令如下:
# 本地模式提交应用spark-submit \--class org.apache.spark.examples.SparkPi \--master local[2] \./examples/jars/spark-examples_2.12-3.1.3.jar \10 # 传给 SparkPi 的参数# --class:表示要执行的程序的主类# --master local[2]# local:没有指定线程数,则所有计算都运行在一个线程当中,没有任何并行计算# local[k]:指定使用k个core来运行计算,比如local[2]就是运行2个core来执行# local[*]:默认模式。自动帮你按照CPU最多核来设置线程数
spark-examples_2.11-2.4.0.jar 是 Spark 提供的测试用例包,SparkPi 用于计算 Pi 值,执行结果如下:

三、Standalone模式
Standalone 是 Spark 提供的一种内置的集群模式,采用内置的资源管理器进行管理。
这个要和Hadoop中的standalone区别开来。这里的standalone是指用Spark来搭建的一个集群,不需要借助Hadoop的Yarn和Mesos等其他框架。
下面按照如图所示演示 1 个 Master 和 2 个 Worker 节点的集群配置:

2.1 集群角色
2.1.1 Master和Worker集群资源管理
Master:Spark特有资源调度系统的Leader。掌管着整个集群的资源信息,类似于Yarn中的ResourceManager。
Worker:Spark特有资源调度系统的Slave,有多个。每个slave掌管着所在节点的资源信息,类似于Yarn中的NodeManager。
Master和Worker是Spark的守护进程、集群资源管理者,即Spark在特定模式(standalone)下正常运行必须要有的后台常驻进程。
2.1.2 Driver和Executor任务的管理者
Driver:Spark Shell中预加载的一个叫做sc的sparkContext对象。
- 把用户程序转为作业(Job)
- 跟踪Executor的任务运行状况
- 为执行器节点调度任务
- UI展示应用运行状况
Executor:负责执行Spark的具体任务。
Driver和Executor是临时程序,当有具体任务提交到Spark集群才会开启的程序。
2.2 环境配置
首先需要保证 Spark 已经解压在两台主机的相同路径上。然后进入 hadoop102 的 ${SPARK_HOME}/conf/ 目录下,拷贝配置样本并进行相关配置:
# cp spark-env.sh.template spark-env.sh
在 spark-env.sh 中配置 JDK 的目录,完成后将该配置使用 scp 命令分发到 hadoop002 上:
# JDK安装位置JAVA_HOME=/usr/java/jdk1.8.0_201
2.3 集群配置
在 ${SPARK_HOME}/conf/ 目录下,拷贝集群配置样本并进行相关配置:
# cp slaves.template slaves
指定所有 Worker 节点的主机名:
# A Spark Worker will be started on each of the machines listed below.hadoop102hadoop103Hadoop104
这里需要注意以下三点:
- 主机名与 IP 地址的映射必须在
/etc/hosts文件中已经配置,否则就直接使用 IP 地址; - 每个主机名必须独占一行;
- Spark 的 Master 主机是通过 SSH 访问所有的 Worker 节点,所以需要预先配置免密登录。
修改spark-env.sh文件,添加master节点
mv spark-env.sh.template spark-env.shvim spark-env.sh# 添加如下代码SPARK MASTER HOST=hadoop102SPARK MASTER PORT=7077
2.4 启动
使用 start-all.sh 代表启动 Master 和所有 Worker 服务。
./sbin/start-master.sh
访问 8080 端口,查看 Spark 的 Web-UI 界面,,此时应该显示有三个有效的工作节点:

2.5 提交作业
# 以client模式提交到standalone集群spark-submit \--class org.apache.spark.examples.SparkPi \--master spark://hadoop102:7077,hadoop103:7077 \--executor-memory 2G \--total-executor-cores 2 \--deploy-mode client \./examples/jars/spark-examples_2.12-3.1.3.jar \10# 以cluster模式提交到standalone集群spark-submit \--class org.apache.spark.examples.SparkPi \--master spark://hadoop102:7077,hadoop103:7077 \--deploy-mode cluster \--supervise \ # 配置此参数代表开启监督,如果主应用程序异常退出,则自动重启 Driver--executor-memory 2G \--total-executor-cores 2 \./examples/jars/spark-examples_2.12-3.1.3.jar \10
standalone client与cluster模式的区别:Driver所在的位置不一样
- client:Driver就在SparkSubmit进程中,此时SparkSubmit进程不能关闭,因为关闭SparkSubmit进程,Driver消失,Driver是负责任务调度,Spark程序会终止。
- cluster:Driver此时运行在任意一个Worker中,此时SparkSubmit进程关闭不影响Driver,spark程序不会终止。
standalone模式任务总资源数配置
- 总核数 =
--total-executor-cores - 总内存数 = (
total-executor-cores/executor-cores) *executor-memory
2.6 可选配置
在虚拟机上提交作业时经常出现一个的问题是作业无法申请到足够的资源:
Initial job has not accepted any resources;check your cluster UI to ensure that workers are registered and have sufficient resources

这时候可以查看 Web UI,我这里是内存空间不足:提交命令中要求作业的 executor-memory 是 2G,但是实际的工作节点的 Memory 只有 1G,这时候你可以修改 --executor-memory,也可以修改 Woker 的 Memory,其默认值为主机所有可用内存值减去 1G。

关于 Master 和 Woker 节点的所有可选配置如下,可以在 spark-env.sh 中进行对应的配置:
| Environment Variable(环境变量) | Meaning(含义) |
|---|---|
SPARK_MASTER_HOST |
master 节点地址 |
SPARK_MASTER_PORT |
master 节点地址端口(默认:7077) |
SPARK_MASTER_WEBUI_PORT |
master 的 web UI 的端口(默认:8080) |
SPARK_MASTER_OPTS |
仅用于 master 的配置属性,格式是 “-Dx=y”(默认:none),所有属性可以参考官方文档:spark-standalone-mode |
SPARK_LOCAL_DIRS |
spark 的临时存储的目录,用于暂存 map 的输出和持久化存储 RDDs。多个目录用逗号分隔 |
SPARK_WORKER_CORES |
spark worker 节点可以使用 CPU Cores 的数量。(默认:全部可用) |
SPARK_WORKER_MEMORY |
spark worker 节点可以使用的内存数量(默认:全部的内存减去 1GB); |
SPARK_WORKER_PORT |
spark worker 节点的端口(默认: random(随机)) |
SPARK_WORKER_WEBUI_PORT |
worker 的 web UI 的 Port(端口)(默认:8081) |
SPARK_WORKER_DIR |
worker 运行应用程序的目录,这个目录中包含日志和暂存空间(default:SPARK_HOME/work) |
SPARK_WORKER_OPTS |
仅用于 worker 的配置属性,格式是 “-Dx=y”(默认:none)。所有属性可以参考官方文档:spark-standalone-mode |
SPARK_DAEMON_MEMORY |
分配给 spark master 和 worker 守护进程的内存。(默认: 1G) |
SPARK_DAEMON_JAVA_OPTS |
spark master 和 worker 守护进程的 JVM 选项,格式是 “-Dx=y”(默认:none) |
SPARK_PUBLIC_DNS |
spark master 和 worker 的公开 DNS 名称。(默认:none) |
三、Spark on Yarn模式
Spark 支持将作业提交到 Yarn 上运行,此时不需要启动 Master 节点,也不需要启动 Worker 节点。
3.1 配置
在 spark-env.sh 中配置 hadoop 的配置目录的位置,可以使用 YARN_CONF_DIR 或 HADOOP_CONF_DIR 进行指定:
YARN_CONF_DIR=/opt/module/hadoop/etc/hadoop
3.2 启动
必须要保证 Hadoop 已经启动,这里包括 YARN 和 HDFS 都需要启动,因为在计算过程中 Spark 会使用 HDFS 存储临时文件,如果 HDFS 没有启动,则会抛出异常。
# start-yarn.sh# start-dfs.sh
3.3 提交应用
# 以client模式提交到yarn集群spark-submit \--class org.apache.spark.examples.SparkPi \--master yarn \--deploy-mode client \--executor-memory 2G \--num-executors 10 \./examples/jars/spark-examples_2.12-3.1.3.jar \10# 以cluster模式提交到yarn集群spark-submit \--class org.apache.spark.examples.SparkPi \--master yarn \--deploy-mode cluster \--executor-memory 2G \--num-executors 10 \./examples/jars/spark-examples_2.12-3.1.3.jar \10
yarn模式任务总资源数配置
- 总核数 =
num-executors*executor-cores - 总内存数 =
num-executors*executor-memory
