SBT 和 spark-submit 之间在 Spark on Yarn 模式下的不同行为 运行 Scala

Different behaviour running Scala in Spark on Yarn mode between SBT and spark-submit

我目前正在尝试使用 Apache Spark 在 yarn(-client) 模式下针对 Cloudera 集群执行一些 Scala 代码,但是 sbt 运行 执行被以下 Java 异常中止:

[error] (run-main-0) org.apache.spark.SparkException: YARN mode not available ?
org.apache.spark.SparkException: YARN mode not available ?
        at org.apache.spark.SparkContext$.org$apache$spark$SparkContext$$createTaskScheduler(SparkContext.scala:1267)
        at org.apache.spark.SparkContext.<init>(SparkContext.scala:199)
        at org.apache.spark.SparkContext.<init>(SparkContext.scala:100)
        at SimpleApp$.main(SimpleApp.scala:7)
        at SimpleApp.main(SimpleApp.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)

Caused by: java.lang.ClassNotFoundException: org.apache.spark.scheduler.cluster.YarnClientClusterScheduler
        at java.net.URLClassLoader.run(URLClassLoader.java:366)
        at java.net.URLClassLoader.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:191)
        at org.apache.spark.SparkContext$.org$apache$spark$SparkContext$$createTaskScheduler(SparkContext.scala:1261)
        at org.apache.spark.SparkContext.<init>(SparkContext.scala:199)
        at org.apache.spark.SparkContext.<init>(SparkContext.scala:100)
        at SimpleApp$.main(SimpleApp.scala:7)
        at SimpleApp.main(SimpleApp.scala)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:606)

[trace] Stack trace suppressed: run last compile:run for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
        at scala.sys.package$.error(package.scala:27)

[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code: 1
15/11/24 17:18:03 INFO network.ConnectionManager: Selector thread was interrupted!
[error] Total time: 38 s, completed 24-nov-2015 17:18:04

我想预构建的 Apache Spark 发行版是用 yarn 支持构建的,因为如果我尝试执行 spark-submit(yarn-client)模式,不再有任何 java 异常,但 yarn 似乎没有分配任何资源,因为我每秒都会收到相同的消息:信息客户端:application_1448366262851_0022 的申请报告(状态:已接受)。我想是因为配置问题。

我用谷歌搜索了最后一条消息,但我不明白我必须修改什么纱线(也不是哪里)配置才能在纱线上使用 spark 执行我的程序。

上下文:

Scala 测试程序:

更新

嗯,SBT 作业失败了,因为 hadoop-client.jar 和 spark-yarn.jar 在 SBT 打包和执行时不在类路径中。

现在,sbt 运行 要求环境变量 SPARK_YARN_APP_JAR 和 SPARK_JAR 我的 build.sbt 配置如下:

name := "File Searcher"
version := "1.0"
scalaVersion := "2.10.4"
librearyDependencies += "org.apache.spark" %% "spark-core" % "0.9.1"
libraryDependencies += "org.apache.spark" %% "spark-yarn" % "0.9.1" % "runtime"
libraryDependencies += "org.apache.hadoop" % "hadoop-client" % "2.6.0" % "runtime"
libraryDependencies += "org.apache.hadoop" % "hadoop-yarn-client" % "2.6.0" % "runtime"
resolvers += "Maven Central" at "https://repo1.maven.org/maven2"

有没有办法配置这些变量"automatically"?我的意思是,我可以设置 SPARK_JAR,因为这个 jar 是随 Spark 安装一起提供的,但是 SPARK_YARN_APP_JAR? 当我手动设置这些变量时,我注意到火花马达不考虑我的自定义配置,即使我设置了 YARN_CONF_DIR 变量。有没有办法告诉 SBT 使用我的本地 Spark 配置来工作?

如果有帮助,我让我正在执行的当前(丑陋)代码:

import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._

object SimpleApp {
  def main(args: Array[String]) {
    val logFile = "src/data/sample.txt"
    val sc = new SparkContext("yarn-client", "Simple App", "C:/spark/lib/spark-assembly-1.3.0-hadoop2.4.0.jar",
      List("target/scala-2.10/file-searcher_2.10-1.0.jar"))
    val logData = sc.textFile(logFile, 2).cache()
    val numTHEs = logData.filter(line => line.contains("the")).count()
    println("Lines with the: %s".format(numTHEs))
  }
}

谢谢!

谢谢 切洛特

好吧,我终于找到问题所在了。

  • 首先,SBT 项目必须包含 spark-core 和 spark-yarn 作为 运行时间依赖项。
  • 接下来,Windows yarn-site.xml 必须指定 Cloudera 集群共享类路径(类路径在 linux 节点上有效)而不是 Windows 作为 yarn 类路径类路径。它使 Yarn 资源管理器知道它的东西在哪里,即使是从 Windows.
  • 执行时也是如此
  • 最后,从 Windows core-site.xml 文件中删除 topology.py 部分,以避免 Spark 尝试执行它,它不需要它来工作。
  • 如果需要,不要忘记删除任何 mapred-site.xml 以使用 Yarn/MR2,并在使用 spark- 时指定在 spark-defaults.conf 中实际定义的所有 spark 属性提交到命令行就运行吧。

就是这样。其他一切都应该有效。