【问题标题】:Spark workers unable to find JAR on EC2 clusterSpark 工作人员无法在 EC2 集群上找到 JAR
【发布时间】:2014-07-04 10:08:41
【问题描述】:

我正在使用 spark-ec2 运行一些 Spark 代码。当我将主人设置为 “本地”,然后它运行良好。但是,当我将 master 设置为 $MASTER 时, 工人立即失败,java.lang.NoClassDefFoundError 为 类。 worker 连接到 master,并显示在 UI 中,并尝试运行任务;但是一旦加载了它的第一个依赖类(在程序集 jar 中),就会立即引发该异常。

我已经使用 sbt-assembly 制作了一个带有类的 jar,确认使用 jar tvf 的类在那里,并设置 SparkConf 分发 类。 Spark Web UI 确实显示了程序集 jar 添加到类路径: http://172.x.x.x47441/jars/myjar-assembly-1.0.jar

看起来,尽管 myjar-assembly 包含 类,并且被添加到集群中,它没有到达 工作人员。我该如何解决? (我需要手动复制jar文件吗? 如果是这样,到哪个目录?我认为 SparkConf 的重点是添加 jars 会自动执行此操作)

我的调试尝试表明:

  1. 正在将程序集 jar 复制到 /root/spark/work/app-xxxxxx/1/ (由 ssh 到 worker 并搜索 jar 来确定)
  2. 但是,该路径不会出现在工作人员的类路径中 (根据日志确定,显示 java -cp 但缺少该文件)

所以,看来我需要告诉 Spark 将路径添加到程序集 jar 到工人的类路径。我怎么做?还是有其他罪魁祸首? (我花了几个小时试图调试它,但无济于事!)

【问题讨论】:

  • 一种可行的解决方法是将 jar 复制到每个工作人员,并将其显式添加到每个工作人员的 SPARK_CLASSPATH
  • 由于这个问题和上面的评论,SPARK_CLASSPATH 现在已被弃用。

标签: amazon-ec2 apache-spark


【解决方案1】:

注意:EC2 特定答案,而不是一般的 Spark 答案。只是想为一年前提出的一个问题提供一个答案,该问题具有相同的症状但通常是不同的原因,并且会绊倒很多人。

如果我对问题的理解正确,您会问:“我需要手动复制 jar 文件吗?如果需要,复制到哪个目录?”你说,“并设置 SparkConf 来分发类”,但你不清楚这是通过 spark-env.sh 还是 spark-defaults.conf 完成的?所以做一些假设,主要是你在集群模式下运行,这意味着你的驱动程序在其中一个工作人员上运行,而你事先不知道哪个工作人员......然后......

答案是肯定的,在类路径中命名的目录。在 EC2 中,唯一的持久数据存储是 /root/persistent-hdfs,但我不知道这是否是个好主意。

In the Spark docs on EC2 I see this line

To deploy code or data within your cluster, you can log in and use
the provided script ~/spark-ec2/copy-dir, which, given a directory 
path, RSYNCs it to the same location on all the slaves.

SPARK_CLASSPATH

我不会使用 SPARK_CLASSPATH,因为它在 Spark 1.0 中已被弃用,所以一个好主意是在 $SPARK_HOME/conf/spark-defaults.conf 中使用它的替换:

spark.executor.extraClassPath /path/to/jar/on/worker

这应该是可行的选项。如果您需要即时执行此操作,而不是在 conf 文件中,建议使用“./spark-submit with --driver-class-path 来扩充驱动程序类路径”(from Spark docs about spark.executor.extraClassPath 并查看另一个答案的结尾来源)。

但是...您没有使用 spark-submit ...我不知道它在 EC2 中是如何工作的,查看脚本我不知道 EC2 在哪里让您在命令行上提供这些参数。您提到您在设置 SparkConf 对象时已经这样做了,所以如果这对您有用,请坚持下去。

我在 Spark-years 看到这是一个非常古老的问题,所以我想知道您是如何解决的?我希望这对某人有所帮助,我在研究 EC2 的细节方面学到了很多东西。


我必须承认,作为对此的限制,它在Spark docs that for spark.executor.extraClassPath 中说:

用户通常不需要设置此选项

我认为他们的意思是大多数人将通过驱动程序配置选项获取类路径。我知道 spark-submit 的大多数文档都让它应该像脚本处理在集群中移动你的代码但我认为这只是在我假设你没有使用的“独立客户端模式”下,我假设 EC2 必须在“独立集群模式。”


关于 SPARK_CLASSPATH 弃用的更多/背景:

更多背景让我想到 SPARK_CLASSPATH is deprecated is this archived thread.this one, crossing the other threadthis one about a WARN message when using SPARK_CLASSPATH

14/07/09 13:37:36 WARN spark.SparkConf:
SPARK_CLASSPATH was detected (set to 'path-to-proprietary-hadoop-lib/*:
/path-to-proprietary-hadoop-lib/lib/*').
This is deprecated in Spark 1.0+.

Please instead use:
 - ./spark-submit with --driver-class-path to augment the driver classpath
 - spark.executor.extraClassPath to augment the executor classpath

【讨论】:

  • 对不起,一些非代码的东西被格式化为代码,我无法将这些部分作为块引用提交问题
  • 以上说了这么多,Spark 文档中仍有部分内容为如何通过集群推送 jars 提供了指导,但即使您可以让驱动程序为您执行此操作,网络流量是一个缺点,它只适用于 spark-submit,而不是 EC2 spark.apache.org/docs/latest/…
【解决方案2】:

您需要在提交您的应用程序时向 spark 集群注册一个 jar,以便您可以按如下方式编辑您的代码。

jars(0) = "/usr/local/spark/lib/spark-assembly-1.3.0-hadoop2.4.0.jar"
val conf: SparkConf = new SparkConf()
.setAppName("Busigence App")
.setMaster(sparkMasterUrl)
.setSparkHome(sparkHome)
.setJars(jars);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 1970-01-01
    • 1970-01-01
    • 2020-11-08
    相关资源
    最近更新 更多