【spark床头书系列】spark-shell 任务提交任务参数选项说明示例源码权威详解

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/sparksubmitclassorg.apache.spark.repl.Mainname"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(
  • 30
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BigDataMLApplication

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值