在YARN上运行Spark

对在 YARN (Hadoop NextGen) 上运行的支持是在 Spark 0.6.0 版本中添加的,并在后续版本中得到了改进。

安全

安全功能,如身份验证,默认情况下是未启用的。当部署一个对互联网或不受信任网络开放的集群时,确保安全访问集群非常重要,以防止未授权的应用程序在集群上运行。在运行Spark之前,请查看 Spark安全性 和本文件中的具体安全部分。

在YARN上启动Spark

确保 HADOOP_CONF_DIR YARN_CONF_DIR 指向包含Hadoop集群的(客户端)配置文件的目录。这些配置用于写入HDFS并连接到YARN资源管理器。该目录中包含的配置将分发到YARN集群,以便应用程序使用的所有容器使用相同的配置。如果配置引用了Java系统属性或YARN未管理的环境变量,则它们也应在Spark应用程序的配置中设置(驱动程序、执行器和在客户端模式下运行时的AM)。

在 YARN 上启动 Spark 应用程序时,可以使用两种部署模式。在 cluster 模式下,Spark 驱动程序在集群上由 YARN 管理的应用程序主进程内运行,客户端在启动应用程序后可以离开。在 client 模式下,驱动程序在客户端进程中运行,应用程序主仅用于从 YARN 请求资源。

与其他由Spark支持的集群管理器不同,在这些管理器中,主节点的地址是在 --master 参数中指定的,在YARN模式下,ResourceManager的地址是从Hadoop配置中读取的。因此, --master 参数是 yarn

要以 cluster 模式启动一个 Spark 应用程序:

$ ./bin/spark-submit --class path.to.your.Class --master yarn --deploy-mode cluster [选项] <应用程序 jar> [应用程序选项]

例如:

$ ./bin/spark-submit --class org.apache.spark.examples.SparkPi \
    --master yarn \
    --deploy-mode cluster \
    --driver-memory 4g \
    --executor-memory 2g \
    --executor-cores 1 \
    --queue thequeue \
    examples/jars/spark-examples*.jar \
    10

上述内容启动了一个 YARN 客户端程序,该程序启动默认的 Application Master。然后 SparkPi 将作为 Application Master 的子线程运行。客户端将定期轮询 Application Master 以获取状态更新,并在控制台中显示它们。一旦您的应用程序运行完毕,客户端将退出。有关如何查看驱动程序和执行器日志,请参阅下面的 调试您的应用程序 部分。

要以 client 模式启动一个 Spark 应用程序,请按相同的方式操作,但将 cluster 替换为 client 。以下显示了如何在 client 模式下运行 spark-shell

$ ./bin/spark-shell --master yarn --deploy-mode client

添加其他 JAR 文件

cluster 模式下,驱动程序运行在与客户端不同的机器上,因此 SparkContext.addJar 不能直接使用客户端本地的文件。为了使客户端上的文件可用于 SparkContext.addJar ,请在启动命令中使用 --jars 选项将它们包含在内。

$ ./bin/spark-submit --class my.main.Class \
    --master yarn \
    --deploy-mode cluster \
    --jars my-other-jar.jar,my-other-other-jar.jar \
    my-main-jar.jar \
    app_arg1 app_arg2

准备工作

在 YARN 上运行 Spark 需要一个支持 YARN 的 Spark 二进制发行版。二进制发行版可以从项目网站的 下载页面 下载。你可以下载两种类型的 Spark 二进制发行版。一种是与特定版本的 Apache Hadoop 预构建的;这个 Spark 发行版包含内置的 Hadoop 运行时,因此我们称之为 with-hadoop Spark 发行版。另一种是与用户提供的 Hadoop 预构建的;由于这个 Spark 发行版不包含内置的 Hadoop 运行时,它更小,但用户必须单独提供 Hadoop 安装。我们称这种变体为 no-hadoop Spark 发行版。对于 with-hadoop Spark 发行版,由于它已经包含了内置的 Hadoop 运行时,默认情况下,当作业提交到 Hadoop Yarn 集群时,为了防止 jar 冲突,它不会将 Yarn 的类路径填充到 Spark 中。要覆盖这种行为,你可以设置 spark.yarn.populateHadoopClasspath=true 。对于 no-hadoop Spark 发行版,Spark 默认会填充 Yarn 的类路径以获取 Hadoop 运行时。对于 with-hadoop Spark 发行版,如果你的应用程序依赖于集群中仅可用的某个库,你可以尝试通过设置上述属性来填充 Yarn 类路径。如果这样做时遇到 jar 冲突问题,你需要关闭此功能并将该库包含在你的应用程序 jar 中。

要自己构建Spark,请参阅 Building Spark

为了使Spark运行时jar文件可以从YARN端访问,您可以指定 spark.yarn.archive spark.yarn.jars 。有关详细信息,请参考 Spark属性 。如果既未指定 spark.yarn.archive 也未指定 spark.yarn.jars ,Spark将创建一个包含所有jar文件的zip文件,位于 $SPARK_HOME/jars 下,并将其上传到分布式缓存。

配置

大多数配置与其他部署模式下的Spark相同。有关更多信息,请参见 配置页面 。这些是特定于Spark on YARN的配置。

调试你的应用程序

在YARN术语中,执行器和应用程序master运行在“容器”内。YARN在应用程序完成后有两种处理容器日志的模式。如果启用了日志聚合(通过 yarn.log-aggregation-enable 配置),容器日志将被复制到HDFS并从本地机器中删除。这些日志可以通过 yarn logs 命令从集群的任何地方查看。

yarn 日志 -applicationId <应用程序 ID>

将打印出来自给定应用程序的所有容器的所有日志文件的内容。您还可以通过 HDFS shell 或 API 直接查看容器日志文件。可以通过查看您的 YARN 配置( yarn.nodemanager.remote-app-log-dir yarn.nodemanager.remote-app-log-dir-suffix )找到它们所在的目录。日志也可以在 Spark Web UI 的 Executors 标签下找到。您需要同时运行 Spark 历史服务器和 MapReduce 历史服务器,并在 yarn-site.xml 中正确配置 yarn.log.server.url 。Spark 历史服务器 UI 上的日志 URL 会将您重定向到 MapReduce 历史服务器,以显示汇总的日志。

当日志聚合未开启时,日志会保留在每台机器的 YARN_APP_LOGS_DIR 本地,一般配置为 /tmp/logs $HADOOP_HOME/logs/userlogs ,具体取决于 Hadoop 的版本和安装方式。查看容器的日志需要访问包含它们的主机,并查看该目录。子目录按应用程序 ID 和容器 ID 组织日志文件。日志也可在 Spark Web UI 的 Executors Tab 下查看,无需运行 MapReduce 历史服务器。

要查看每个容器的启动环境,请将 yarn.nodemanager.delete.debug-delay-sec 增加到一个较大的值(例如 36000 ),然后通过 yarn.nodemanager.local-dirs 访问应用程序缓存,访问那些启动容器的节点。该目录包含启动脚本、JAR文件和用于启动每个容器的所有环境变量。这个过程对于调试类路径问题特别有用。(请注意,启用此功能需要对集群设置的管理员权限以及重启所有节点管理器。因此,这不适用于托管集群)。

要为应用程序主控或执行器使用自定义的log4j配置,以下是一些选项:

请注意,对于第一个选项,执行器和应用程序主控将共享相同的 log4j 配置,这可能会在它们在同一个节点上运行时造成问题(例如,试图写入同一个日志文件)。

如果您需要参考在 YARN 中放置日志文件的正确位置,以便 YARN 能够正确显示和聚合它们,请在您的 log4j2.properties 中使用 spark.yarn.app.container.log.dir 。例如, appender.file_appender.fileName=${sys:spark.yarn.app.container.log.dir}/spark.log 。对于流式应用程序,配置 RollingFileAppender 并将文件位置设置为 YARN 的日志目录,将避免因大型日志文件导致的磁盘溢出,并且可以使用 YARN 的日志工具访问日志。

要为应用程序主控和执行者使用自定义 metrics.properties,更新 $SPARK_CONF_DIR/metrics.properties 文件。它将与其他配置自动上传,因此您不需要手动使用 --files 指定它。

Spark 属性

属性名称 默认值 含义 自版本起
spark.yarn.am.memory 512m 用于客户端模式下YARN应用程序主节点的内存量,格式与JVM内存字符串相同(例如 512m 2g )。 在集群模式下,请改用 spark.driver.memory

使用小写后缀,例如 k m g t p ,分别表示千字节、兆字节、吉字节、泰字节和佩比字节。
1.3.0
spark.yarn.am.resource.{resource-type}.amount (无) 用于客户端模式下YARN应用程序主节点的资源量。 在集群模式下,请改用 spark.yarn.driver.resource. .amount 。 请注意,此功能仅适用于YARN 3.0+ 参考YARN资源模型文档:https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/ResourceModel.html

示例: 要向YARN请求GPU资源,请使用: spark.yarn.am.resource.yarn.io/gpu.amount
3.0.0
spark.yarn.applicationType SPARK 定义更具体的应用程序类型,例如 SPARK SPARK-SQL SPARK-STREAMING SPARK-MLLIB SPARK-GRAPH 。请注意字符数不得超过20个。 3.1.0
spark.yarn.driver.resource.{resource-type}.amount (无) 用于集群模式下YARN应用程序主节点的资源量。 请注意,此功能仅适用于YARN 3.0+ 参考YARN资源模型文档:https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/ResourceModel.html

示例: 要向YARN请求GPU资源,请使用: spark.yarn.driver.resource.yarn.io/gpu.amount
3.0.0
spark.yarn.executor.resource.{resource-type}.amount (无) 每个执行器进程使用的资源量。 请注意,此功能仅适用于YARN 3.0+ 参考YARN资源模型文档:https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/ResourceModel.html

示例: 要向YARN请求GPU资源,请使用: spark.yarn.executor.resource.yarn.io/gpu.amount
3.0.0
spark.yarn.resourceGpuDeviceName yarn.io/gpu 指定Spark资源类型 gpu 与表示GPU的YARN资源之间的映射。默认情况下,YARN使用 yarn.io/gpu ,但如果YARN已配置为使用自定义资源类型,则可以重新映射它。 使用 spark.{driver/executor}.resource.gpu.* 配置时适用。 3.2.1
spark.yarn.resourceFpgaDeviceName yarn.io/fpga 指定Spark资源类型 fpga 与表示FPGA的YARN资源之间的映射。默认情况下,YARN使用 yarn.io/fpga ,但如果YARN已配置为使用自定义资源类型,则可以重新映射它。 使用 spark.{driver/executor}.resource.fpga.* 配置时适用。 3.2.1
spark.yarn.am.cores 1 用于客户端模式下YARN应用程序主节点使用的核心数量。 在集群模式下,请改用 spark.driver.cores 1.3.0
spark.yarn.am.waitTime 100s 仅在 cluster 模式下使用。YARN应用程序主节点等待SparkContext初始化的时间。 1.3.0
spark.yarn.submit.file.replication 默认HDFS复制(通常为 3 上传到HDFS的应用程序文件的HDFS复制级别。这些包括Spark jar、应用程序jar以及任何分布式缓存文件/档案。 0.8.1
spark.yarn.stagingDir 当前用户在文件系统中的主目录 提交应用程序时使用的临时目录。 2.0.0
spark.yarn.preserve.staging.files false 设置为 true 以在作业结束时保留临时文件(Spark jar、应用程序jar、分布式缓存文件),而不是将其删除。 1.1.0
spark.yarn.scheduler.heartbeat.interval-ms 3000 Spark应用程序主节点在YARN ResourceManager中心跳的间隔(以毫秒为单位)。 该值限制为YARN配置的过期间隔的一半,即 yarn.am.liveness-monitor.expiry-interval-ms 0.8.1
spark.yarn.scheduler.initial-allocation.interval 200ms 在存在待处理容器分配请求时,Spark应用程序主节点主动心跳到YARN ResourceManager的初始间隔。它不应大于 spark.yarn.scheduler.heartbeat.interval-ms 。如果仍有待处理容器,则分配间隔将在后续主动心跳中加倍,直到达到 spark.yarn.scheduler.heartbeat.interval-ms 1.4.0
spark.yarn.historyServer.address (无) Spark历史服务器的地址,例如 host.com:18080 。地址不应包含方案( http:// )。由于历史服务器是可选服务,因此默认未设置此地址。此地址在Spark应用程序完成时提供给YARN ResourceManager,以便将应用程序从ResourceManager UI链接到Spark历史服务器UI。 对于此属性,可以使用YARN属性作为变量,这些变量在运行时由Spark替换。例如,如果Spark历史服务器在与YARN ResourceManager相同的节点上运行,则可以将其设置为 ${hadoopconf-yarn.resourcemanager.hostname}:18080 1.0.0
spark.yarn.dist.archives (无) 以逗号分隔的档案列表,要提取到每个执行器的工作目录中。 1.0.0
spark.yarn.dist.files (无) 以逗号分隔的文件列表,要放置在每个执行器的工作目录中。 1.0.0
spark.yarn.dist.jars (无) 以逗号分隔的jar列表,要放置在每个执行器的工作目录中。 2.0.0
spark.yarn.dist.forceDownloadSchemes (无) 以逗号分隔的方案列表,将在添加到YARN的分布式缓存之前下载到本地磁盘。用于YARN服务不支持Spark支持的方案(如http、https和ftp)或必须位于本地YARN客户端类路径中的jar的情况。通配符 '*' 表示为所有方案下载资源。 2.3.0
spark.executor.instances 2 静态分配的执行器数量。使用 spark.dynamicAllocation.enabled 时,初始的执行器集至少会这么大。 1.0.0
spark.yarn.am.memoryOverhead AM内存 * 0.10,最低为384 spark.driver.memoryOverhead 相同,但适用于客户端模式下的YARN应用程序主节点。 1.3.0
spark.yarn.queue default 提交应用程序的YARN队列名称。 1.0.0
spark.yarn.jars (无) 包含要分发到YARN容器的Spark代码的库列表。 默认情况下,Spark在YARN上将使用本地安装的Spark jar,但Spark jar也可以在HDFS中的任何可被所有用户读取的位置。这样,YARN就可以将其缓存到节点上,以便在每次运行应用程序时不必再次分发。要指向HDFS上的jar,例如,将此配置设置为 hdfs:///some/path 。可以使用通配符。 2.0.0
spark.yarn.archive (无) 包含所需Spark jars的档案,以便分发到YARN缓存。如果设置,则该配置将替换 spark.yarn.jars ,并且档案将在所有应用程序的容器中使用。该档案应包含jar文件在其根目录中。 与上一选项一样,该档案也可以托管在HDFS上,以加快文件分发。 2.0.0
spark.yarn.appMasterEnv.[EnvironmentVariableName] (无) 将由 EnvironmentVariableName 指定的环境变量添加到在YARN上启动的应用程序主节点进程中。用户可以指定多个此类变量以设置多个环境变量。在 cluster 模式下,这控制Spark驱动程序的环境,而在 client 模式下,仅控制执行器启动器的环境。 1.1.0
spark.yarn.containerLauncherMaxThreads 25 在YARN应用程序主节点中用于启动执行器容器的最大线程数。 1.2.0
spark.yarn.am.extraJavaOptions (无) 要传递给客户端模式下YARN应用程序主节点的额外JVM选项字符串。 在集群模式下,请改用 spark.driver.extraJavaOptions 。请注意,使用此选项无法设置最大堆大小(-Xmx)设置。最大堆大小设置可以通过 spark.yarn.am.memory 设置。 1.3.0
spark.yarn.am.extraLibraryPath (无) 在客户端模式下启动YARN应用程序主节点时,设置要使用的特殊库路径。 1.4.0
spark.yarn.populateHadoopClasspath 对于 with-hadoop Spark发行版,该值设置为false; 对于 no-hadoop 发行版,该值设置为true。 是否从 yarn.application.classpath mapreduce.application.classpath 填充Hadoop类路径。请注意,如果将其设置为 false ,则需要具有打包Hadoop运行时的 with-Hadoop Spark发行版,或者用户必须单独提供Hadoop安装。 2.4.6
spark.yarn.maxAppAttempts yarn.resourcemanager.am.max-attempts 在YARN中 将尝试提交应用程序的最大次数。 它应不大于YARN配置中全局最大尝试次数。 1.3.0
spark.yarn.am.attemptFailuresValidityInterval (无) 定义AM失败跟踪的有效性间隔。 如果AM已运行至少定义的间隔,则AM失败计数将被重置。 如果未配置,则不启用此功能。 1.6.0
spark.yarn.am.clientModeTreatDisconnectAsFailed false 将yarn-client不干净的断开连接视为失败。在yarn-client模式下,通常情况下,应用程序总是会以最终状态为SUCCESS结束,因为在某些情况下,无法确定应用程序是被用户有意终止的还是发生了真实错误。此配置会更改该行为,使得如果应用程序主节点与驱动程序不干净地断开连接(即没有进行适当的关闭握手),应用程序将以最终状态FAILED终止。这将允许调用者决定这是否真的是真正的失败。请注意,如果设置了此配置且用户仅错误地终止了客户端应用程序,可能会显示状态为FAILED,但实际上并没有真正失败。 3.3.0
spark.yarn.am.clientModeExitOnError false 在yarn-client模式下,当此值为true时,如果驱动程序获得具有最终状态KILLED或FAILED的应用程序报告,驱动程序将停止相应的SparkContext并以代码1退出程序。 请注意,如果此值为true并且从另一个应用程序调用,它将终止父应用程序。 3.3.0
spark.yarn.am.tokenConfRegex (无) 此配置的值是一个正则表达式,用于从作业的配置文件(例如hdfs-site.xml)中grep出配置条目列表并发送到RM,在续订委派令牌时使用。此功能的典型用例是支持在YARN集群需要与多个下游HDFS集群通信的环境中,其中YARN RM可能没有连接到这些集群的配置(例如,dfs.nameservices、dfs.ha.namenodes.*、dfs.namenode.rpc-address.*)。 在这种情况下,Spark用户可以将配置值指定为 ^dfs.nameservices$|^dfs.namenode.rpc-address.*$|^dfs.ha.namenodes.*$ ,以从作业的本地配置文件中解析这些HDFS配置。此配置与 mapreduce.job.send-token-conf 非常相似。有关更多详细信息,请查看YARN-5910。 3.3.0
spark.yarn.submit.waitAppCompletion true 在YARN集群模式下,控制客户端是否等待退出直到应用程序完成。 如果设置为 true ,则客户端进程将保持活动状态,报告应用程序的状态。 否则,客户端进程将在提交后退出。 1.4.0
spark.yarn.am.nodeLabelExpression (无) YARN节点标签表达式,限制AM将要调度的节点集。 仅支持版本大于或等于2.6的YARN版本,因此在早期版本下运行时,将忽略此属性。 1.6.0
spark.yarn.executor.nodeLabelExpression (无) YARN节点标签表达式,限制将调度的执行器的节点集。 仅支持版本大于或等于2.6的YARN版本,因此在早期版本下运行时,将忽略此属性。 1.4.0
spark.yarn.tags (无) 以逗号分隔的字符串列表,作为YARN应用程序标签出现在YARN应用程序报告中,可用于在查询YARN应用程序时进行过滤。 1.5.0
spark.yarn.priority (无) 应用程序在YARN中的优先级,以定义待处理应用程序的排序策略,具有更高整数值的应用程序更有机会被激活。目前,YARN仅支持在使用FIFO排序策略时的应用程序优先级。 3.0.0
spark.yarn.config.gatewayPath (无) 在网关主机(Spark应用程序启动的主机)上有效的路径,但可能与集群中其他节点上相同资源的路径不同。结合 spark.yarn.config.replacementPath ,用于支持具有异构配置的集群,以便Spark能够正确启动远程进程。

替换路径通常会包含对YARN导出的一些环境变量的引用(因此对Spark容器可见)。

例如,如果网关节点在 /disk1/hadoop 上安装了Hadoop库,并且Hadoop安装位置由YARN作为 HADOOP_HOME 环境变量导出,则将此值设置为 /disk1/hadoop ,将替换路径设置为 $HADOOP_HOME ,确保用于启动远程进程的路径正确引用本地YARN配置。
1.5.0
spark.yarn.config.replacementPath (无) 参见 spark.yarn.config.gatewayPath 1.5.0
spark.yarn.rolledLog.includePattern (无) Java正则表达式,用于过滤与定义的包含模式匹配的日志文件,这些日志文件将以滚动方式聚合。 这将与YARN的滚动日志聚合一起使用,以启用此功能,YARN侧 yarn.nodemanager.log-aggregation.roll-monitoring-interval-seconds 应在yarn-site.xml中进行配置。Spark log4j附加器需要更改为使用FileAppender或其他可以处理在运行时被删除的文件的附加器。根据在log4j配置中配置的文件名(如spark.log),用户应设置正则表达式(spark*)以包括所有需要聚合的日志文件。 2.0.0
spark.yarn.rolledLog.excludePattern (无) Java正则表达式,用于过滤与定义的排除模式匹配的日志文件,这些日志文件将不会以滚动方式聚合。如果日志文件名同时匹配包含模式和排除模式,则最终将排除此文件。 2.0.0
spark.yarn.executor.launch.excludeOnFailure.enabled false 启用排除那些存在YARN资源分配问题的节点的标志。 用于排除的错误限制可以通过 spark.excludeOnFailure.application.maxFailedExecutorsPerNode 配置。 2.4.0
spark.yarn.exclude.nodes (无) 以逗号分隔的YARN节点名称列表,这些节点被排除在资源分配之外。 3.0.0
spark.yarn.metrics.namespace (无) AM指标报告的根命名空间。 如果未设置,则使用YARN应用程序ID。 2.4.0
spark.yarn.report.interval 1s 集群模式下当前Spark作业状态报告之间的间隔。 0.9.0
spark.yarn.report.loggingFrequency 30 处理到下一个应用程序状态记录的最大应用程序报告数量。如果状态发生变化,则无论处理的应用程序报告数量如何,都会记录应用程序状态。 3.5.0
spark.yarn.clientLaunchMonitorInterval 1s 启动应用时请求客户端模式AM状态之间的间隔。 2.3.0
spark.yarn.includeDriverLogsLink false 在集群模式下,客户端应用程序报告是否包含指向驱动程序容器日志的链接。这需要轮询ResourceManager的REST API,因此会对RM施加一些额外负载。 3.1.0
spark.yarn.unmanagedAM.enabled false 在客户端模式下,是否将应用程序主节点服务作为客户端的一部分启动,使用非管控的am。 3.0.0
spark.yarn.shuffle.server.recovery.disabled false 设置为true以满足安全要求更高的应用程序,并更愿意不在数据库中保存其密钥。此类应用程序的混洗数据将在外部混洗服务重启后无法恢复。 3.5.0

SHS自定义执行器日志URL的可用模式

模式 意义
{{HTTP_SCHEME}} http:// https:// ,根据 YARN HTTP 策略。(通过 yarn.http.policy 配置)
{{NM_HOST}} 运行容器的节点的“主机”。
{{NM_PORT}} 运行容器的节点管理器的“端口”。
{{NM_HTTP_PORT}} 运行容器的节点管理器的 HTTP 服务器的“端口”。
{{NM_HTTP_ADDRESS}} 分配给容器的节点的 HTTP URI。
{{CLUSTER_ID}} 资源管理器的集群 ID。(通过 yarn.resourcemanager.cluster-id 配置)
{{CONTAINER_ID}} 容器的 ID。
{{USER}} 系统环境中的 SPARK_USER
{{FILE_NAME}} stdout stderr

例如,假设您想直接将日志 URL 链接指向作业历史服务器,而不是让 NodeManager http 服务器对其进行重定向,您可以按照以下方式配置 spark.history.custom.executor.log.url

{{HTTP_SCHEME}} : /jobhistory/logs/{{NM_HOST}}:{{NM_PORT}}/{{CONTAINER_ID}}/{{CONTAINER_ID}}/{{USER}}/{{FILE_NAME}}?start=-4096

注意:您需要将 替换为实际值。

资源分配和配置概述

请确保您已阅读 配置页面 上的自定义资源调度和配置概述部分。本节仅讨论YARN特定的资源调度方面。

YARN 需要配置以支持用户希望与 Spark 使用的任何资源。YARN 3.1.0 中添加了对资源调度的支持。有关配置资源和正确设置隔离的更多信息,请参阅 YARN 文档。理想情况下,这些资源应设置为隔离状态,以便执行器只能看到其分配的资源。如果您没有启用隔离,则用户负责创建一个发现脚本,以确保资源不会在执行器之间共享。

YARN 支持用户定义的资源类型,但内置了 GPU ( yarn.io/gpu ) 和 FPGA ( yarn.io/fpga ) 类型。因此,如果您使用其中任一资源,Spark 可以将您对 Spark 资源的请求转换为 YARN 资源,您只需指定 spark.{driver/executor}.resource. 配置。请注意,如果您在 YARN 中使用的是自定义的 GPU 或 FPGA 资源类型,您可以使用 spark.yarn.resourceGpuDeviceName spark.yarn.resourceFpgaDeviceName 更改 Spark 映射。如果您使用的是 FPGA 或 GPU 以外的资源,用户需要负责为 YARN ( spark.yarn.{driver/executor}.resource. ) 和 Spark ( spark.{driver/executor}.resource. ) 指定配置。

例如,用户希望为每个执行器请求 2 个 GPU。用户只需指定 spark.executor.resource.gpu.amount=2 ,Spark 将处理从 YARN 请求 yarn.io/gpu 资源类型。

如果用户定义了一个 YARN 资源,我们称之为 acceleratorX ,那么用户必须指定 spark.yarn.executor.resource.acceleratorX.amount=2 spark.executor.resource.acceleratorX.amount=2

YARN 不会告诉 Spark 每个容器分配的资源地址。因此,用户必须指定一个发现脚本,该脚本在启动时由执行器运行,以发现该执行器可用的资源。您可以在 examples/src/main/scripts/getGpusResources.sh 中找到示例脚本。该脚本必须设置可执行权限,用户应设置权限以不允许恶意用户修改它。该脚本应向标准输出写入一个 JSON 字符串,格式为 ResourceInformation 类。这包含资源名称和仅适用于该执行器的资源地址数组。

阶段级调度概述

在YARN上支持阶段级调度:

需要注意的一件事是,YARN特定的是每个ResourceProfile在YARN上需要一个不同的容器优先级。映射简单,即ResourceProfile的id变为优先级,在YARN中,数字越小优先级越高。这意味着早期创建的配置文件在YARN中将具有更高的优先级。通常,这并不重要,因为Spark在开始另一个阶段之前会完成一个阶段,唯一可能受影响的情况是在作业服务器类型的场景中,因此这是需要牢记的。注意,在基础默认配置文件和自定义ResourceProfiles之间,用户自定义资源的处理方式是不同的。为了允许用户请求带有额外资源的YARN容器,而不通过Spark调度,用户可以通过 spark.yarn.executor.resource. 配置来指定资源。不过,这些配置仅在基础默认配置文件中使用,并不会传播至其他自定义ResourceProfiles。这是因为如果你希望某个阶段不使用它们,就没有办法将它们移除。这导致你的默认配置文件中包含在 spark.yarn.executor.resource. 中定义的自定义资源以及Spark定义的GPU或FPGA资源。Spark将GPU和FPGA资源转换为YARN内置类型 yarn.io/gpu yarn.io/fpga ,但不知道其他资源的映射。任何其他Spark自定义资源不会传播到默认配置文件的YARN中。因此,如果你希望Spark基于自定义资源进行调度并从YARN请求它,必须在YARN( spark.yarn.{driver/executor}.resource. )和Spark( spark.{driver/executor}.resource. )配置中同时指定它。如果你只想要YARN容器带有额外资源,而不希望Spark使用它们,则可省略Spark配置。至于自定义ResourceProfiles,目前没有仅指定YARN资源而不通过Spark调度的方式。这意味着对于自定义ResourceProfiles,我们将ResourceProfile中定义的所有资源传播到YARN。我们仍然将GPU和FPGA转换为YARN内置类型。这要求你指定的任何自定义资源的名称与其在YARN中定义时的名称相匹配。

重要说明

凯尔伯罗斯

Spark中的标准Kerberos支持在 安全 页面中介绍。

在YARN模式下,当访问Hadoop文件系统时,除了Hadoop配置中的默认文件系统外,Spark还会自动获取托管Spark应用程序临时目录的服务的委派令牌。

YARN特定的Kerberos配置

属性名称 默认值 含义 自版本起
spark.kerberos.keytab (无) 指定主角的密钥表文件的完整路径。此密钥表将通过 YARN 分布式缓存复制到运行 YARN 应用程序主控的节点, 并将用于定期更新登录票据和委派令牌。等同于 --keytab 命令行参数。
(也适用于“本地”主控。)
3.0.0
spark.kerberos.principal (无) 在安全集群上运行时,用于登录 KDC 的主体。等同于 --principal 命令行参数。
(也适用于“本地”主控。)
3.0.0
spark.yarn.kerberos.relogin.period 1m 检查是否需要更新 kerberos TGT 的频率。此值应设置为短于 TGT 更新周期(或如果未启用 TGT 更新,则为 TGT 生命周期)。 默认值对于大多数部署来说应该足够。 2.3.0
spark.yarn.kerberos.renewal.excludeHadoopFileSystems (无) 一组以逗号分隔的 Hadoop 文件系统的列表,其主机将被排除在资源调度程序的委派令牌更新之外。 例如, spark.yarn.kerberos.renewal.excludeHadoopFileSystems=hdfs://nn1.com:8032, hdfs://nn2.com:8032 。目前已知可以在 YARN 下工作,因此 YARN 资源管理器不会为该应用程序更新令牌。 请注意,由于资源调度程序不更新令牌,因此任何运行时间超过原始令牌过期时间的应用程序尝试使用该令牌时很可能会失败。 3.2.0

排查 Kerberos 问题

调试 Hadoop/Kerberos 问题可能是“困难”的。一个有用的技巧是通过设置 HADOOP_JAAS_DEBUG 环境变量来启用 Hadoop 中 Kerberos 操作的额外日志记录。

导出 HADOOP_JAAS_DEBUG=true

JDK类可以通过系统属性 sun.security.krb5.debug sun.security.spnego.debug=true 配置为启用额外的Kerberos和SPNEGO/REST身份验证日志记录

-Dsun.security.krb5.debug=true -Dsun.security.spnego.debug=true

所有这些选项都可以在应用程序主控中启用:

spark.yarn.appMasterEnv.HADOOP_JAAS_DEBUG true
spark.yarn.am.extraJavaOptions -Dsun.security.krb5.debug=true -Dsun.security.spnego.debug=true

最后,如果 org.apache.spark.deploy.yarn.Client 的日志级别设置为 DEBUG ,日志将包含获取的所有令牌的列表及其过期详情

配置外部洗牌服务

要在您的 YARN 集群中的每个 NodeManager 上启动 Spark Shuffle 服务,请遵循以下说明:

  1. 使用 YARN配置文件 构建Spark。如果您使用的是预打包的发行版,请跳过此步骤。
  2. 找到 spark- -yarn-shuffle.jar 。如果您自己构建Spark,它应该位于 $SPARK_HOME/common/network-yarn/target/scala- 下,如果您使用的是发行版,它应该位于 yarn 下。
  3. 将此jar添加到集群中所有 NodeManager 的类路径中。
  4. 在每个节点的 yarn-site.xml 中,将 spark_shuffle 添加到 yarn.nodemanager.aux-services 中,然后将 yarn.nodemanager.aux-services.spark_shuffle.class 设置为 org.apache.spark.network.yarn.YarnShuffleService
  5. 通过在 etc/hadoop/yarn-env.sh 中设置 YARN_HEAPSIZE (默认值为1000)来增加 NodeManager 的堆大小,以避免在洗牌期间出现垃圾回收问题。
  6. 重新启动集群中的所有 NodeManager

当洗牌服务在YARN上运行时,以下额外的配置选项可用:

属性名称 默认值 含义 自版本起
spark.yarn.shuffle.stopOnFailure false 当 Spark Shuffle 服务初始化失败时,是否停止 NodeManager。这可以防止在未运行 Spark Shuffle 服务的 NodeManagers 上运行容器导致的应用程序失败。 2.1.0
spark.yarn.shuffle.service.metrics.namespace sparkShuffleService 在将 shuffle 服务指标发射到 NodeManager 的 Hadoop metrics2 系统时使用的命名空间。 3.2.0
spark.yarn.shuffle.service.logs.namespace (未设置) 当形成用于发射 YARN shuffle 服务日志的记录器名称时,将附加到类名上的命名空间,例如 org.apache.spark.network.yarn.YarnShuffleService.logsNamespaceValue 。由于某些日志框架可能期望记录器名称看起来像类名,通常建议提供一个有效的 Java 包或类名,并且不包含空格。 3.3.0
spark.shuffle.service.db.backend LEVELDB 当在 YARN 中启用保留工作重启时,用于指定在 shuffle 服务状态存储中使用的磁盘基础存储,支持 `LEVELDB` 和 `ROCKSDB`,默认值为 `LEVELDB`。在当前情况下,`LevelDB/RocksDB` 的原始数据存储不会自动转换为另一种类型的存储。原始数据存储将保留,当切换存储类型时将创建新类型的数据存储。 3.4.0

请注意,上述说明假设使用了默认的洗牌服务名称, spark_shuffle 。这里可以使用任何名称,但在 YARN NodeManager 配置中使用的值必须与 Spark 应用程序中 spark.shuffle.service.name 的值匹配。

默认情况下,洗牌服务将从由NodeManager使用的Hadoop配置中获取所有配置(例如, yarn-site.xml )。然而,也可以使用名为 spark-shuffle-site.xml 的文件独立配置洗牌服务,该文件应放置在洗牌服务的类路径上(默认情况下,与NodeManager的类路径共享)。洗牌服务将把它视为标准的Hadoop配置资源,并在NodeManager的配置之上进行叠加。

使用 Apache Oozie 启动您的应用程序

Apache Oozie 可以作为工作流的一部分启动 Spark 应用程序。在安全集群中,启动的应用程序需要相关的令牌以访问集群的服务。如果 Spark 使用 keytab 启动,则这一过程是自动的。但是,如果 Spark 要在没有 keytab 的情况下启动,则必须将设置安全性的责任交给 Oozie。

关于为安全集群配置 Oozie 以及获取作业凭证的详细信息,请访问 Oozie 网站 ,查看特定版本文档中的“身份验证”部分。

对于 Spark 应用程序,必须设置 Oozie 工作流,以便 Oozie 请求应用程序所需的所有令牌,包括:

为了避免Spark尝试——然后失败——获取Hive、HBase和远程HDFS令牌,必须将Spark配置设置为禁用这些服务的令牌收集。

Spark 配置必须包含以下行:

spark.security.credentials.hive.enabled   假
spark.security.credentials.hbase.enabled  假

配置选项 spark.kerberos.access.hadoopFileSystems 必须未设置。

使用 Spark 历史服务器替代 Spark Web UI

可以使用Spark历史服务器应用程序页面作为运行应用程序的跟踪URL,当应用程序UI被禁用时。这在安全集群上可能是可取的,或者为了减少Spark驱动程序的内存使用。要通过Spark历史服务器设置跟踪,请执行以下操作:

请注意,历史服务器信息可能与应用程序的状态不一致。

运行多个版本的 Spark Shuffle 服务

请注意,本节仅适用于运行在 YARN 版本 >= 2.9.0 的情况下。

在某些情况下,运行多个使用不同版本 Spark 的 Shuffle 服务实例可能是有利的。例如,当运行一个 YARN 集群,其中包含运行多个 Spark 版本的混合工作负载时,这可能会很有帮助,因为给定版本的 Shuffle 服务并不总是与其他版本的 Spark 兼容。从 2.9.0 开始的 YARN 版本支持在隔离的类加载器中运行 Shuffle 服务 (见 YARN-4577 ),这意味着多个 Spark 版本可以在单个 NodeManager 中共存。 yarn.nodemanager.aux-services. .classpath 及从 YARN 2.10.2/3.1.1/3.2.0 开始, yarn.nodemanager.aux-services. .remote-classpath 选项可用于配置此项。请注意,YARN 3.3.0/3.3.1 存在一个问题,需要将 yarn.nodemanager.aux-services. .system-classes 设置为解决方法。有关详细信息,请参见 YARN-11053 。除了设置单独的类路径外,还需要确保两个版本对不同的端口进行广播。 这可以通过上述描述的 spark-shuffle-site.xml 文件来实现。例如,您可能有如下配置:

 yarn.nodemanager.aux-services = spark_shuffle_x,spark_shuffle_y
yarn.nodemanager.aux-services.spark_shuffle_x.classpath = /path/to/spark-x-path/fat.jar:/path/to/spark-x-config
yarn.nodemanager.aux-services.spark_shuffle_y.classpath = /path/to/spark-y-path/fat.jar:/path/to/spark-y-config

或者

 yarn.nodemanager.aux-services = spark_shuffle_x,spark_shuffle_y
yarn.nodemanager.aux-services.spark_shuffle_x.classpath = /path/to/spark-x-path/*:/path/to/spark-x-config
yarn.nodemanager.aux-services.spark_shuffle_y.classpath = /path/to/spark-y-path/*:/path/to/spark-y-config

这两个 spark-*-config 目录各包含一个文件, spark-shuffle-site.xml 。这些是 Hadoop 配置格式 的 XML 文件,每个文件包含几个配置项,用于调整使用的端口号和指标名称前缀:



spark.shuffle.service.port
7001


spark.yarn.shuffle.service.metrics.namespace
sparkShuffleServiceX


这两个不同服务的值应该是不同的。

然后,在Spark应用的配置中,应配置为:

 spark.shuffle.service.name = spark_shuffle_x
spark.shuffle.service.port = 7001

并且应该配置为:

 spark.shuffle.service.name = spark_shuffle_y
spark.shuffle.service.port = <其他值>