无法将Apache Spark应用程序提交到容器化群集

时间:2017-12-17 16:33:59

标签: apache-spark apache-spark-2.0 spark-submit

我在使用spark-submit和内部REST API运行Spark应用程序时遇到问题。我要演示的部署方案是Spark在我的本地笔记本电脑上作为集群运行。

为此,我为spark-master和spark-worker创建了两个Docker容器。这一切似乎都在工作,工作人员可以注册master,两个Web控制台都可用,内部REST(端口6066)API响应。

我已经为我的应用程序创建了一个超级jar,但是,在尝试执行它时,我在两种情况下都会遇到相同的错误。

使用spark-submit时,我在本地使用本地Spark安装提交到容器:

$SPARK_HOME/bin/spark-submit \
    --class com.reynoldsm88.jobs.SparkApp \
    --master spark://localhost:7077 \
    --deploy-mode cluster \
    --supervise \
    /Users/reynoldsm88/workspace/spark-app/spark-app/target/scala-2.11/spark-app-assembly-0.0.1-SNAPSHOT.jar

使用REST API时,我的请求如下所示:

curl -X POST http://localhost:6066/v1/submissions/create --header "Content-Type:application/json;charset=UTF-8" --data '{
    "action" : "CreateSubmissionRequest",
    "appArgs" : [ "myAppArgument1" ],
    "appResource" : "/Users/reynoldsm88/workspace/spark-app/spark-app/target/scala-2.11/spark-app-assembly-0.0.1-SNAPSHOT.jar",
    "clientSparkVersion" : "2.2.0",
      "environmentVariables" : {
        "SPARK_ENV_LOADED" : "1"
    },
    "mainClass" : "com.reynoldsm88.jobs.SparkApp",
    "sparkProperties" : {
        "spark.master" : "spark://localhost:7077",
        "spark.jars" : "/Users/reynoldsm88/workspace/spark-app/spark-app/target/scala-2.11/spark-app-assembly-0.0.1-SNAPSHOT.jar",
        "spark.driver.supervise" : "false",
        "spark.app.name" : "MyJob",
        "spark.eventLog.enabled": "true",
        "spark.submit.deployMode" : "client"
    }
}'

两者的结果是相同的:

Spark Master(在Docker容器内)

17/12/17 16:08:23 INFO Master: Driver submitted org.apache.spark.deploy.worker.DriverWrapper
17/12/17 16:08:23 INFO Master: Launching driver driver-20171217160823-0001 on worker worker-20171217155536-172.17.0.5-7078
17/12/17 16:08:24 INFO Master: Removing driver: driver-20171217160823-0001

Spark Worker(在单独的Docker容器内)

17/12/17 16:08:24 INFO Worker: Asked to launch driver driver-20171217160823-0001
17/12/17 16:08:24 INFO DriverRunner: Copying user jar file:///Users/reynoldsm88/workspace/spark-app/spark-app/target/scala-2.11/spark-app-assembly-0.0.1-SNAPSHOT.jar to /spark-2.2.0-bin-hadoop2.7/work/driver-20171217160823-0001/spark-app-assembly-0.0.1-SNAPSHOT.jar
17/12/17 16:08:24 INFO Utils: Copying /Users/reynoldsm88/workspace/spark-app/spark-app/target/scala-2.11/spark-app-assembly-0.0.1-SNAPSHOT.jar to /spark-2.2.0-bin-hadoop2.7/work/driver-20171217160823-0001/spark-app-assembly-0.0.1-SNAPSHOT.jar
17/12/17 16:08:24 INFO DriverRunner: Killing driver process!
17/12/17 16:08:24 WARN Worker: Driver driver-20171217160823-0001 failed with unrecoverable exception: java.nio.file.NoSuchFileException: /Users/reynoldsm88/workspace/spark-app/spark-app/target/scala-2.11/spark-app-assembly-0.0.1-SNAPSHOT.jar

我可能会被误解,但我认为在这两种情况下,本地JAR文件都将提交给Spark master,以便分发给工作节点。但是,由于某种原因,它看起来好像工作节点正在尝试从我的本地文件系统加载它,这是有问题的,因为Spark Worker运行的Docker容器不知道这个文件。

也许我误解了这是如何运作的?如果我真的想将笔记本电脑中的应用程序提交到容器化群集,我是否需要将该目录作为卷或主机JAR安装到某处,以便工作人员可以下载它?

非常感谢任何帮助或见解。

1 个答案:

答案 0 :(得分:0)

发布后不久,我想出了解决问题的方法,但我想知道这是不是很理想,或者有更好的方法。作为作业脚本的一部分,我将jar复制到一个目录中,该目录作为主机卷挂载在Docker a la:

<强> Dockerfile

...
VOLUME /etc/spark/apps
...

启动脚本

docker run -v /Users/reynoldsm88/spark/apps/:/etc/spark/apps --name spark-master -p 8080:8080 -p 7077:7077 -p 6066:6066 -t reynoldsm88/spark-master

这似乎适用于我现在的需求。我希望有一种方法可以通过API将Spark部署到Spark,尽管在我的研究中我可能错过了它。