无法将 Apache Spark 应用程序提交到容器化集群
Posted
技术标签:
【中文标题】无法将 Apache Spark 应用程序提交到容器化集群【英文标题】:Trouble Submitting Apache Spark Application to Containerized Cluster 【发布时间】:2017-12-17 16:33:59 【问题描述】:我在使用 spark-submit 和内部 REST API 运行 Spark 应用程序时遇到问题。我想演示的部署场景是 Spark 在我的本地笔记本电脑上作为集群运行。
为此,我为 spark-master 和 spark-worker 创建了两个 Docker 容器。这方面的一切似乎都在工作,worker 能够向 master 注册,两个 Web 控制台都可用,并且内部 REST(端口 6066)API 是响应式的。
我已经为我的应用程序创建了一个 uber 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 以便 Worker 可以下载它?
任何帮助或见解将不胜感激。
【问题讨论】:
【参考方案1】:发布后不久,我想出了一个解决我的问题的方法,但我想知道这是理想的还是有更好的方法。作为作业脚本的一部分,我将 jar 复制到一个目录中,该目录在 Docker 中作为主机卷挂载:
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 将 JAR 部署到 Spark,尽管我可能在研究中错过了这一点。
【讨论】:
以上是关于无法将 Apache Spark 应用程序提交到容器化集群的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 SSO 钱包将 Oracle 与 Apache Spark 连接
Apache Spark:CentOS7下的提交和执行一个官方的jar项目包