在 YARN 上运行 Spark

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

安全

默认情况下不启用身份验证等安全功能。在部署开放给互联网或不受信任的网络的集群时,务必保护对集群的访问,以防止未经授权的应用程序在集群上运行。在运行 Spark 之前,请参阅 Spark 安全和本文档中的特定安全部分。

在 YARN 上启动 Spark

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

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

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

要在 cluster 模式下启动 Spark 应用程序

$ ./bin/spark-submit --class path.to.your.Class --master yarn --deploy-mode cluster [options] <app jar> [app options]

例如

$ ./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 以获取状态更新,并在控制台中显示它们。一旦你的应用程序运行完成,客户端将退出。有关如何查看 driver 和 executor 日志,请参阅下面的调试你的应用程序部分。

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

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

添加其他 JAR 包

cluster 模式下,driver 在与客户端不同的机器上运行,因此 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 的 classpath 填充到 Spark 中。要覆盖此行为,你可以设置 spark.yarn.populateHadoopClasspath=true。对于 no-hadoop Spark 分发包,Spark 默认会填充 Yarn 的 classpath 以获取 Hadoop 运行时。对于 with-hadoop Spark 分发包,如果你的应用程序依赖于集群中才可用的某个库,你可以尝试通过设置上面提到的属性来填充 Yarn classpath。如果你因此遇到 jar 冲突问题,则需要将其关闭并将此库包含在你的应用程序 jar 中。

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

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

配置

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

调试你的应用程序

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

yarn logs -applicationId <app ID>

将打印给定应用程序中所有容器的所有日志文件的内容。你还可以使用 HDFS shell 或 API 直接在 HDFS 中查看容器日志文件。可以通过查看 YARN 配置(yarn.nodemanager.remote-app-log-diryarn.nodemanager.remote-app-log-dir-suffix)来找到它们的位置。日志也可以在 Spark Web UI 的 Executors 选项卡下获得。你需要同时运行 Spark history server 和 MapReduce history server,并在 yarn-site.xml 中正确配置 yarn.log.server.url。Spark history server UI 上的日志 URL 将重定向到 MapReduce history server 以显示聚合的日志。

当未启用日志聚合时,日志将保留在每台机器上的本地 YARN_APP_LOGS_DIR 下,该目录通常根据 Hadoop 版本和安装配置为 /tmp/logs$HADOOP_HOME/logs/userlogs。查看容器的日志需要转到包含它们的宿主机,并在该目录中查找。子目录按应用程序 ID 和容器 ID 组织日志文件。日志也可以在 Spark Web UI 的 Executors 选项卡下获得,并且不需要运行 MapReduce history server。

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

要为 application master 或 executor 使用自定义 log4j2 配置,请使用以下选项

请注意,对于第一个选项,executor 和 application master 将共享相同的 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 的日志实用程序访问日志。

要为 application master 和 executor 使用自定义的 metrics.properties,请更新 $SPARK_CONF_DIR/metrics.properties 文件。 它将与其他配置一起自动上传,因此您无需使用 --files 手动指定它。

Spark 属性

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

使用小写后缀,例如 kmgtp,分别表示 kibi-、mebi-、gibi-、tebi- 和 pebibytes。

1.3.0
spark.yarn.am.resource.{resource-type}.amount (无) 在客户端模式下用于 YARN Application Master 的资源量。 在集群模式下,请改用 spark.yarn.driver.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.am.resource.yarn.io/gpu.amount

3.0.0
spark.yarn.applicationType SPARK 定义更具体的应用程序类型,例如 SPARKSPARK-SQLSPARK-STREAMINGSPARK-MLLIBSPARK-GRAPH。 请注意不要超过 20 个字符。 3.1.0
spark.yarn.driver.resource.{resource-type}.amount (无) 在集群模式下用于 YARN Application Master 的资源量。 请注意,此功能只能与 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 (无) 每个 executor 进程使用的资源量。 请注意,此功能只能与 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 Application Master 的内核数。 在集群模式下,请改用 spark.driver.cores 1.3.0
spark.yarn.am.waitTime 100s 仅在 cluster 模式下使用。 YARN Application Master 等待 SparkContext 初始化的时间。 1.3.0
spark.yarn.submit.file.replication 默认的 HDFS 复制因子(通常为 3 上传到 HDFS 以供应用程序使用的文件的 HDFS 复制级别。 这些文件包括 Spark jar、应用程序 jar 和任何分布式缓存文件/存档。 0.8.1
spark.yarn.stagingDir 文件系统中当前用户的 home 目录 提交应用程序时使用的暂存目录。 2.0.0
spark.yarn.preserve.staging.files false 设置为 true 可在作业结束时保留暂存文件(Spark jar、应用程序 jar、分布式缓存文件),而不是删除它们。 1.1.0
spark.yarn.scheduler.heartbeat.interval-ms 3000 Spark 应用程序 master 向 YARN ResourceManager 发送心跳的间隔(以毫秒为单位)。 该值上限为 YARN 配置中过期时间间隔的一半,即 yarn.am.liveness-monitor.expiry-interval-ms 0.8.1
spark.yarn.scheduler.initial-allocation.interval 200ms 当存在挂起的容器分配请求时,Spark 应用程序 master 积极向 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 (无) 要提取到每个 executor 的工作目录中的归档文件的逗号分隔列表。 1.0.0
spark.yarn.dist.files (无) 要放置在每个 executor 的工作目录中的文件的逗号分隔列表。 1.0.0
spark.yarn.dist.jars (无) 要放置在每个 executor 的工作目录中的 jar 文件的逗号分隔列表。 2.0.0
spark.yarn.dist.forceDownloadSchemes (无) 将资源添加到 YARN 的分布式缓存之前,将资源下载到本地磁盘的方案的逗号分隔列表。 用于 YARN 服务不支持 Spark 支持的方案(如 http、https 和 ftp)或需要位于本地 YARN 客户端类路径中的 jar 的情况。 通配符 '*' 表示下载所有方案的资源。 2.3.0
spark.executor.instances 2 静态分配的 executor 数量。 使用 spark.dynamicAllocation.enabled,executor 的初始集合将至少这么大。 1.0.0
spark.yarn.am.memoryOverhead AM 内存 * 0.10,最小值为 384 spark.driver.memoryOverhead 相同,但用于客户端模式下的 YARN Application Master。 1.3.0
spark.yarn.queue default 将应用程序提交到的 YARN 队列的名称。 1.0.0
spark.yarn.jars (无) 包含要分发到 YARN 容器的 Spark 代码的库列表。 默认情况下,YARN 上的 Spark 将使用本地安装的 Spark jar,但 Spark jar 也可以位于 HDFS 上可全局读取的位置。 这允许 YARN 将其缓存在节点上,以便每次运行应用程序时都不需要分发它。 例如,要指向 HDFS 上的 jar,请将此配置设置为 hdfs:///some/path。 允许使用 Globs。 2.0.0
spark.yarn.archive (无) 包含需要分发到 YARN 缓存的 Spark jar 的归档文件。 如果设置了此配置,则此配置将替换 spark.yarn.jars,并且该归档文件将用于应用程序的所有容器中。 该归档文件应在其根目录中包含 jar 文件。 与前面的选项一样,该归档文件也可以托管在 HDFS 上,以加快文件分发速度。 2.0.0
spark.yarn.appMasterEnv.[EnvironmentVariableName] (无) 将由 EnvironmentVariableName 指定的环境变量添加到在 YARN 上启动的 Application Master 进程。 用户可以指定多个这些变量并设置多个环境变量。 在 cluster 模式下,这将控制 Spark driver 的环境,而在 client 模式下,它仅控制 executor 启动器的环境。 1.1.0
spark.yarn.containerLauncherMaxThreads 25 YARN Application Master 中用于启动 executor 容器的最大线程数。 1.2.0
spark.yarn.am.extraJavaOptions (无) 传递给客户端模式下的 YARN Application Master 的额外 JVM 选项的字符串。 在集群模式下,请改用 spark.driver.extraJavaOptions。 请注意,使用此选项设置最大堆大小 (-Xmx) 设置是非法的。 可以使用 spark.yarn.am.memory 设置最大堆大小设置。 1.3.0
spark.yarn.am.extraLibraryPath (无) 设置一个特殊的库路径,用于在客户端模式下启动 YARN Application Master。 1.4.0
spark.yarn.populateHadoopClasspath 对于 with-hadoop Spark 发行版,此设置为 false;对于 no-hadoop 发行版,此设置为 true。 是否从 yarn.application.classpathmapreduce.application.classpath 填充 Hadoop 类路径。 请注意,如果将其设置为 false,则需要捆绑 Hadoop 运行时的 with-Hadoop Spark 发行版,或者用户必须单独提供 Hadoop 安装。 2.4.6
spark.yarn.maxAppAttempts YARN 中的 yarn.resourcemanager.am.max-attempts 尝试提交应用程序的最大次数。 它不应大于 YARN 配置中的最大尝试次数。 1.3.0
spark.yarn.am.attemptFailuresValidityInterval (无) 定义 AM 故障跟踪的有效时间间隔。如果 AM 已经运行了至少定义的间隔,AM 故障计数将被重置。如果未配置,则此功能不启用。 1.6.0
spark.yarn.am.clientModeTreatDisconnectAsFailed false 将 yarn-client 的非正常断开连接视为失败。在 yarn-client 模式下,通常应用程序总是以 SUCCESS 的最终状态结束,因为在某些情况下,无法知道应用程序是被用户有意终止还是发生了真正的错误。此配置更改了该行为,使得如果 Application Master 与驱动程序非正常断开连接(即没有适当的关闭握手),则应用程序将以 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,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 节点标签表达式,用于限制 executors 将被调度到的节点集合。只有大于或等于 2.6 的 YARN 版本支持节点标签表达式,因此在针对早期版本运行时,此属性将被忽略。 1.4.0
spark.yarn.tags (无) 逗号分隔的字符串列表,作为 YARN 应用程序标签传递,这些标签出现在 YARN ApplicationReports 中,可用于在查询 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-site.xml 中配置 yarn.nodemanager.log-aggregation.roll-monitoring-interval-seconds。需要更改 Spark log4j appender 以使用 FileAppender 或其他可以处理在运行时被删除的文件的 appender。基于 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 1 秒 集群模式下,当前 Spark 作业状态报告之间的间隔。 0.9.0
spark.yarn.report.loggingFrequency 30 在记录下一个应用程序状态之前处理的最大应用程序报告数。如果状态发生更改,无论处理的应用程序报告数量如何,都将记录应用程序状态。 3.5.0
spark.yarn.clientLaunchMonitorInterval 1 秒 启动应用程序时,客户端模式 AM 的状态请求之间的间隔。 2.3.0
spark.yarn.includeDriverLogsLink false 在集群模式下,客户端应用程序报告是否包含指向驱动程序容器日志的链接。这需要轮询 ResourceManager 的 REST API,因此会给 RM 带来一些额外的负载。 3.1.0
spark.yarn.unmanagedAM.enabled false 在客户端模式下,是否使用非托管 am 作为客户端的一部分启动 Application Master 服务。 3.0.0
spark.yarn.shuffle.server.recovery.disabled false 对于安全性要求较高且希望其密钥不保存在数据库中的应用程序,请设置为 true。此类应用程序的 shuffle 数据将在 External Shuffle Service 重新启动后不会恢复。 3.5.0

SHS 自定义 executor 日志 URL 的可用模式

Pattern含义
{{HTTP_SCHEME}} 根据 YARN HTTP 策略,为 http://https://。(通过 yarn.http.policy 配置)
{{NM_HOST}} 容器运行所在的节点 "host"。
{{NM_PORT}} 容器运行所在的节点管理器 "port"。
{{NM_HTTP_PORT}} 容器运行所在的节点管理器的 http 服务器 "port"。
{{NM_HTTP_ADDRESS}} 分配容器的节点的 Http URI。
{{CLUSTER_ID}} Resource Manager 的集群 ID。(通过 yarn.resourcemanager.cluster-id 配置)
{{CONTAINER_ID}} 容器的 ID。
{{USER}} 系统环境中的 SPARK_USER
{{FILE_NAME}} stdout, stderr.

例如,假设您想直接将日志 URL 链接指向 Job History Server,而不是让 NodeManager http 服务器重定向它,您可以将 spark.history.custom.executor.log.url 配置为如下

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

注意:您需要将 <JHS_HOST><JHS_PORT> 替换为实际值。

资源分配和配置概述

请务必阅读配置页面上的“自定义资源调度和配置概述”部分。本节仅讨论资源调度的 YARN 特定方面。

需要配置 YARN 以支持用户想要与 Spark 一起使用的任何资源。 YARN 上的资源调度是在 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.resourceGpuDeviceNamespark.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=2spark.executor.resource.acceleratorX.amount=2

YARN 不会告诉 Spark 分配给每个容器的资源的地址。 因此,用户必须指定一个发现脚本,该脚本由启动时由执行程序运行,以发现该执行程序可用的资源。您可以在 examples/src/main/scripts/getGpusResources.sh 中找到示例脚本。 该脚本必须设置执行权限,并且用户应设置权限以不允许恶意用户对其进行修改。 该脚本应以 ResourceInformation 类的格式将 JSON 字符串写入 STDOUT。 它具有资源名称和仅该执行程序可用的资源地址数组。

Stage 级别调度概述

YARN 支持阶段级别调度

需要注意的是,YARN 特有的一个特性是,每个 ResourceProfile 都需要在 YARN 上使用不同的容器优先级。映射关系很简单,ResourceProfile 的 ID 就是优先级,在 YARN 中,数字越小优先级越高。这意味着较早创建的 profile 在 YARN 中具有更高的优先级。通常情况下,这不会有影响,因为 Spark 在启动下一个 stage 之前会完成一个 stage。唯一可能产生影响的情况是在作业服务器类型的场景中,因此需要注意这一点。注意,基础默认 profile 和自定义 ResourceProfile 之间处理自定义资源的方式存在差异。为了允许用户请求具有额外资源的 YARN 容器,而不在其上进行 Spark 调度,用户可以通过 spark.yarn.executor.resource. 配置来指定资源。但是,这些配置仅在基础默认 profile 中使用,不会传播到任何其他自定义 ResourceProfile 中。这是因为如果您希望某个 stage 不具有这些资源,则无法删除它们。这导致您的默认 profile 获取在 spark.yarn.executor.resource. 中定义的自定义资源,以及 Spark 定义的 GPU 或 FPGA 资源。Spark 将 GPU 和 FPGA 资源转换为 YARN 内置类型 yarn.io/gpu) 和 yarn.io/fpga,但不知道任何其他资源的映射。任何其他 Spark 自定义资源都不会传播到 YARN 以用于默认 profile。因此,如果您希望 Spark 基于自定义资源进行调度,并从 YARN 请求该资源,则必须在 YARN (spark.yarn.{driver/executor}.resource.) 和 Spark (spark.{driver/executor}.resource.) 配置中都指定它。如果您只想让 YARN 容器具有额外的资源,而 Spark 不使用它们进行调度,则不要添加 Spark 配置。现在对于自定义 ResourceProfile,目前没有仅指定 YARN 资源而不使用 Spark 进行调度的方法。这意味着对于自定义 ResourceProfile,我们将 ResourceProfile 中定义的所有资源传播到 YARN。我们仍然将 GPU 和 FPGA 转换为 YARN 内置类型。这要求您指定的任何自定义资源的名称与它们在 YARN 中定义的名称相匹配。

重要提示

Kerberos

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

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

YARN 特定的 Kerberos 配置

属性名称默认值含义起始版本
spark.kerberos.keytab (无) 包含上面指定的 principal 的 keytab 的完整路径。此 keytab 将通过 YARN Distributed Cache 复制到运行 YARN Application Master 的节点,并将用于定期续订登录票证和委托令牌。等效于 --keytab 命令行参数。
(也适用于“本地” master。)
3.0.0
spark.kerberos.principal (无) 在安全集群上运行时,用于登录 KDC 的 principal。等效于 --principal 命令行参数。
(也适用于“本地” master。)
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 Resource Manager 不会续订应用程序的令牌。请注意,由于资源调度程序不续订令牌,因此任何运行时间超过原始令牌到期时间的应用程序尝试使用该令牌都可能失败。 3.2.0

Kerberos 故障排除

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

export HADOOP_JAAS_DEBUG=true

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

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

所有这些选项都可以在 Application Master 中启用

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,则日志将包含所有获得的令牌及其到期详细信息的列表

配置外部 Shuffle 服务

要在 YARN 集群中的每个 NodeManager 上启动 Spark Shuffle Service,请按照以下说明操作

  1. 使用 YARN profile 构建 Spark。如果您使用的是预先打包的发行版,请跳过此步骤。
  2. 找到 spark-<version>-yarn-shuffle.jar。如果您自己构建 Spark,则它应该位于 $SPARK_HOME/common/network-yarn/target/scala-<version> 下,如果您使用的是发行版,则它应该位于 yarn 下。
  3. 将此 jar 添加到集群中所有 NodeManager 的 classpath 中。
  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's 堆大小,以避免 shuffle 期间出现垃圾回收问题。
  6. 重新启动集群中的所有 NodeManager

当 shuffle service 在 YARN 上运行时,可以使用以下额外的配置选项

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

请注意,上述说明假定已使用默认的 shuffle service 名称 spark_shuffle。可以在此处使用任何名称,但 YARN NodeManager 配置中使用的值必须与 Spark 应用程序中 spark.shuffle.service.name 的值匹配。

默认情况下,shuffle service 将从 NodeManager 使用的 Hadoop 配置(例如 yarn-site.xml)中获取其所有配置。但是,也可以使用名为 spark-shuffle-site.xml 的文件独立配置 shuffle service,该文件应放置在 shuffle service 的 classpath 上(默认情况下,该 classpath 与 NodeManager 的 classpath 共享)。shuffle service 会将其视为标准的 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   false
spark.security.credentials.hbase.enabled  false

必须取消设置配置选项 spark.kerberos.access.hadoopFileSystems

使用 Spark History Server 替换 Spark Web UI

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

请注意,history server 信息可能与应用程序的状态不是最新的。

运行多个版本的 Spark Shuffle Service

请注意,本节仅适用于在 YARN 版本 >= 2.9.0 上运行时。

在某些情况下,可能需要运行多个 Spark Shuffle Service 实例,这些实例使用不同的 Spark 版本。例如,当运行一个 YARN 集群,其中混合了运行多个 Spark 版本的应用程序时,这会很有用,因为给定版本的 shuffle service 并不总是与其他 Spark 版本兼容。自 2.9.0 以来的 YARN 版本支持在隔离的类加载器中运行 shuffle service 的功能(请参阅 YARN-4577),这意味着多个 Spark 版本可以共存于单个 NodeManager 中。可以使用 yarn.nodemanager.aux-services.<service-name>.classpath 选项,以及从 YARN 2.10.2/3.1.1/3.2.0 开始的 yarn.nodemanager.aux-services.<service-name>.remote-classpath 选项来配置这一点。请注意,YARN 3.3.0/3.3.1 存在一个问题,需要设置 yarn.nodemanager.aux-services.<service-name>.system-classes 作为解决方法。详情请参阅 YARN-11053。除了设置单独的 classpath 之外,还需要确保这两个版本通告到不同的端口。这可以使用上面描述的 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 文件,每个文件都包含一些配置来调整端口号和使用的指标名称前缀

<configuration>
  <property>
    <name>spark.shuffle.service.port</name>
    <value>7001</value>
  </property>
  <property>
    <name>spark.yarn.shuffle.service.metrics.namespace</name>
    <value>sparkShuffleServiceX</value>
  </property>
</configuration>

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

然后,在 Spark 应用程序的配置中,一个应该配置为:

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

另一个应该配置为:

  spark.shuffle.service.name = spark_shuffle_y
  spark.shuffle.service.port = <other value>