spark-shell 任务提交任务参数选项说明示例源码详解点击这里看全文
文章目录
参数说明
常规选项:
选项 | 描述 |
---|---|
--master MASTER_URL |
指定Spark的Master地址,可以是spark://host:port、mesos://host:port、yarn或k8s://https://host:port,或者本地模式local[](默认值为local[])。 |
--deploy-mode DEPLOY_MODE |
指定应用程序在集群中是以客户端模式(“client”)还是集群模式(“cluster”)启动,默认为客户端模式(client)。 |
--class CLASS_NAME |
指定应用程序的主类(适用于Java / Scala应用程序)。 |
--name NAME |
指定应用程序的名称。 |
--jars JARS |
指定要包含在驱动程序和执行器类路径中的jar文件的逗号分隔列表。 |
--packages |
指定要包含在驱动程序和执行器类路径中的jar文件的Maven坐标列表。将搜索本地maven仓库,然后搜索maven中央仓库以及–repositories参数指定的其他远程仓库。坐标的格式应为groupId:artifactId:version。 |
--exclude-packages |
指定要在解析–packages参数提供的依赖项时排除的groupId:artifactId列表,以避免依赖冲突。 |
--repositories |
指定额外的远程仓库列表,用逗号分隔,用于搜索与–packages参数给出的Maven坐标对应的jar文件。 |
--py-files PY_FILES |
指定要放置在Python应用程序的PYTHONPATH中的.zip、.egg或.py文件的逗号分隔列表。 |
--files FILES |
指定要放置在每个执行器的工作目录中的文件的逗号分隔列表。可以通过SparkFiles.get(fileName)来访问执行器中这些文件的文件路径。 |
--conf PROP=VALUE |
指定Spark配置属性,格式为PROP=VALUE。 |
--properties-file FILE |
指定要加载额外属性的文件路径。如果未指定,则会查找conf/spark-defaults.conf文件。 |
--driver-memory MEM |
指定驱动程序的内存(例如1000M、2G)(默认值为1024M)。 |
--driver-java-options |
指定传递给驱动程序的额外Java选项。 |
--driver-library-path |
指定传递给驱动程序的额外库路径条目。 |
--driver-class-path |
指定传递给驱动程序的额外类路径条目。注意,使用–jars参数添加的jar文件将自动包含在类路径中。 |
--executor-memory MEM |
指定每个执行器的内存(例如1000M、2G)(默认值为1G)。 |
--proxy-user NAME |
提交应用程序时要模拟的用户。该参数不能与–principal / --keytab一起使用。 |
--help, -h |
显示帮助信息并退出。 |
--verbose, -v |
打印额外的调试输出。 |
--version |
打印当前Spark的版本号。 |
仅在集群模式下生效:
选项 | 描述 |
---|---|
--driver-cores NUM |
驱动程序使用的核心数,仅在集群模式下生效(默认值为1)。 |
仅适用于YARN:
选项 | 描述 |
---|---|
--queue QUEUE_NAME |
提交应用程序的YARN队列(默认值为"default")。 |
--num-executors NUM |
要启动的执行器数量(默认值为2)。如果启用了动态分配,初始执行器数量至少为NUM。 |
--archives ARCHIVES |
要解压缩到每个执行器的工作目录中的存档文件列表,以逗号分隔。 |
--principal PRINCIPAL |
在运行时连接到安全HDFS时要使用的principal。 |
--keytab KEYTAB |
包含上述principal的keytab文件的完整路径。该keytab文件将通过安全分布式缓存(Secure Distributed Cache)复制到运行应用程序主节点的节点上,以便定期更新登录票据和委派令牌。 |
仅适用于Spark Standalone或者Mesos的集群模式:
选项 | 描述 |
---|---|
--supervise |
如果指定了该参数,在失败时重新启动驱动程序。 |
--kill SUBMISSION_ID |
如果指定了该参数,杀死指定的驱动程序。 |
--status SUBMISSION_ID |
如果指定了该参数,请求指定驱动程序的状态信息。 |
仅适用于Spark Standalone和Mesos:
选项 | 描述 |
---|---|
--total-executor-cores NUM |
所有执行器的总核心数。 |
仅适用于Spark Standalone和YARN:
选项 | 描述 |
---|---|
--executor-cores NUM |
每个执行器使用的核心数(默认值为1,YARN模式下为所有可用核心数)。 |
示例
local
# 在本地使用8个内核线程local模式运行应用程序
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master local[8] \
/path/to/examples.jar \
100
Spark Standalone
# 在Spark Standalone独立集群中以client部署模式运行
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://207.184.161.138:7077 \
--executor-memory 20G \
--total-executor-cores 100 \
/path/to/examples.jar \
1000
# 在Spark Standalone独立集群中以cluster部署模式和supervise运行
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master spark://207.184.161.138:7077 \
--deploy-mode cluster \
--supervise \
--executor-memory 20G \
--total-executor-cores 100 \
/path/to/examples.jar \
1000
# 在Spark Standalone独立集群上运行Python应用程序
./bin/spark-submit \
--master spark://207.184.161.138:7077 \
examples/src/main/python/pi.py \
1000
yarn
# 在YARN集群上运行
export HADOOP_CONF_DIR=XXX
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master yarn \
--deploy-mode cluster \
--executor-memory 20G \
--num-executors 50 \
/path/to/examples.jar \
1000
Mesos
# 在Mesos集群中以cluster部署模式和supervise运行
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master mesos://207.184.161.138:7077 \
--deploy-mode cluster \
--supervise \
--executor-memory 20G \
--total-executor-cores 100 \
http://path/to/examples.jar \
1000
Kubernetes
# 在Kubernetes集群中以cluster部署模式运行
./bin/spark-submit \
--class org.apache.spark.examples.SparkPi \
--master k8s://xx.yy.zz.ww:443 \
--deploy-mode cluster \
--executor-memory 20G \
--num-executors 50 \
http://path/to/examples.jar \
1000
spark-shell源码解析
执行过程
1.首先,检查是否在Cygwin环境中运行,并设置一个变量cygwin来标识。
2.然后,它进入bash的posix模式,并检查环境变量SPARK_HOME是否为空,如果为空,则调用find-spark-home脚本来寻找Spark的安装路径。
3.接下来,它设置了一个名为_SPARK_CMD_USAGE的环境变量,用于显示Spark Shell的使用方法。然后,它通过设置SPARK_SUBMIT_OPTS环境变量,将"-Dscala.usejavacp=true"添加到SPARK_SUBMIT_OPTS中,以解决Scala和Java类路径之间的问题。
4.最后,它定义了一个名为main的函数,该函数根据操作系统类型和终端设置的不同方式启动Spark Shell。在main函数内部,它首先保存终端设置,然后在发生中断时恢复终端设置并退出。整个脚本的退出状态码会被记录并传播。
spark-shell源码
# 检查是否在Cygwin环境中运行,并设置cygwin变量标识
case "$(uname)" in
CYGWIN*) cygwin=true;;
esac
# 进入bash的posix模式
set -o posix
# 如果SPARK_HOME环境变量为空,则调用find-spark-home脚本来寻找Spark的安装路径
if [ -z "${SPARK_HOME}" ]; then
source "$(dirname "$0")"/find-spark-home
fi
# 定义Spark Shell的使用方法
export _SPARK_CMD_USAGE="Usage: ./bin/spark-shell [options]
Scala REPL options:
-I <file> 预加载 <file>,强制逐行解释"
# 解决Scala不假设使用Java类路径的问题
SPARK_SUBMIT_OPTS="$SPARK_SUBMIT_OPTS -Dscala.usejavacp=true"
# main函数,启动Spark Shell
function main() {
if $cygwin; then
# 解决JLine和Cygwin之间的问题
stty -icanon min 1 -echo > /dev/null 2>&1
export SPARK_SUBMIT_OPTS="$SPARK_SUBMIT_OPTS -Djline.terminal=unix"
"${SPARK_HOME}"/bin/spark-submit --class org.apache.spark.repl.Main --name "Spark shell" "$@"
stty icanon echo > /dev/null 2>&1
else
export SPARK_SUBMIT_OPTS
"${SPARK_HOME}"/bin/spark-submit --class org.apache.spark.repl.Main --name "Spark shell" "$@"
fi
}
# 保存终端设置和退出状态
exit_status=127
saved_stty=""
# 恢复stty设置(尤其是回显)
function restoreSttySettings() {
stty $saved_stty
saved_stty=""
}
# 在被中断之前重新启用回显
trap onExit INT
# 保存终端设置
saved_stty=$(stty -g 2>/dev/null)
# 如果执行失败,则清除错误,以免后续尝试恢复它们
if [[ ! $? ]]; then
saved_stty=""
fi
# 主函数的入口
main "$@"
# 记录退出状态,以防被覆盖
exit_status=$?
onExit
“ S P A R K H O M E " / b i n / s p a r k − s u b m i t − − c l a s s o r g . a p a c h e . s p a r k . r e p l . M a i n − − n a m e " S p a r k s h e l l " " {SPARK_HOME}"/bin/spark-submit --class org.apache.spark.repl.Main --name "Spark shell" " SPARKHOME"/bin/spark−submit−−classorg.apache.spark.repl.Main−−name"Sparkshell""@”
spark-shell脚本使用了spark-submit 和类org.apache.spark.repl.Main,下面进行分析
入口类Main源码
org.apache.spark.repl.Main
是Spark中负责启动Spark REPL(Read-Eval-Print Loop)的主要入口点。Spark REPL是一个交互式解释器,允许用户在Spark集群上进行实时的数据分析和处理。
package org.apache.spark.repl
import java.io.File
import java.net.URI
import java.util.Locale
import scala.tools.nsc.GenericRunnerSettings
import org.apache.spark._
import org.apache.spark.internal.Logging
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.internal.StaticSQLConf.CATALOG_IMPLEMENTATION
import org.apache.spark.util.Utils
object Main extends Logging {
// 初始化日志
initializeLogIfNecessary(true)
Signaling.cancelOnInterrupt()
val conf = new SparkConf()
val rootDir = conf.getOption("spark.repl.classdir").getOrElse(Utils.getLocalDir(conf))
val outputDir = Utils.createTempDir(root = rootDir, namePrefix = "repl")
var sparkContext: SparkContext = _
var sparkSession: SparkSession = _
// 这是一个公共变量,因为测试会重置它
var interp: SparkILoop = _
private var hasErrors = false
private var isShellSession = false
private def scalaOptionError(msg: String): Unit = {
hasErrors = true
// scalastyle:off println
Console.err.println(msg)
// scalastyle:on println
}
def main(args: Array[String]): Unit = {
isShellSession = true
doMain(args, new SparkILoop)
}
// 可见于测试
private[repl] def doMain(args: Array[String], _interp: SparkILoop): Unit = {
interp = _interp
val jars = Utils.getLocalUserJarsForShell(conf)
// 如果存在,删除每个jar的file:///, file://或file:/方案
.map {
x => if (x.startsWith("file:")) new File(new URI(x)).getPath else x }
.mkString(File.pathSeparator)
val interpArguments = List(
"-Yrepl-class-based",
"-Yrepl-outdir", s"${
outputDir.getAbsolutePath}",
"-classpath", jars
) ++ args.toList
val settings = new GenericRunnerSettings(scalaOptionError)
settings.processArguments(interpArguments, true)
if (!hasErrors) {
interp.process(settings) // Repl开始并进入循环
Option(sparkContext).foreach(_.stop)
}
}
def createSparkSession(): SparkSession = {
try {
val execUri = System.getenv("SPARK_EXECUTOR_URI")
conf.setIfMissing("spark.app.name", "Spark shell")
// SparkContext将检测此配置并在RpcEnv的文件服务器上注册它,将spark.repl.class.uri设置为执行器使用的实际URI。这有点丑陋,但由于执行器在某些情况下作为SparkContext初始化的一部分启动,存在一个初始化顺序问题,阻止在实例化SparkContext之后设置此值。
conf.set("spark.repl.class.outputDir", outputDir.getAbsolutePath())
if (execUri != null) {
conf.set("spark.executor.uri", execUri)
}
if (System.getenv("SPARK_HOME") != null) {
conf.setSparkHome(System.getenv("SPARK_HOME"))
}
val builder = SparkSession.builder.config(conf)
if (conf.get(CATALOG_IMPLEMENTATION.key, "hive").toLowerCase(Locale.ROOT) == "hive") {
if (SparkSession.hiveClassesArePresent) {
// 在该属性根本未设置的情况下,构建器的配置不会将此值设置为'hive'。原始默认行为是当存在hive类时,使用hive目录。
sparkSession = builder.enableHiveSupport().getOrCreate(