我想通过Web应用程序向用户公开我的Spark应用程序。
基本上,用户可以决定他想要运行哪个动作并输入一些需要传递给spark应用程序的变量。 例如:用户输入几个字段,然后单击一个按钮,该按钮执行以下操作"使用参数min_x,max_x,min_y,max_y"运行 sparkApp1 。
应使用用户提供的参数启动spark应用程序。完成后,可能需要Web应用程序来检索结果(来自hdfs或mongodb)并将其显示给用户。处理时,Web应用程序应显示Spark应用程序的状态。
我的问题:
我正在运行带有YARN / Mesos(尚不确定)和MongoDB的Spark 1.6.1集群。
答案 0 :(得分:34)
基本上你可以使用SparkLauncher类来启动Spark应用程序并添加一些监听器来监视进度。
但是您可能对Livy服务器感兴趣,Livy服务器是Spark作业的RESTful Sever。据我所知,Zeppelin正在使用Livy提交工作并检索状态。
您还可以使用Spark REST界面检查状态,然后信息将更加精确。 Here有一个例子如何通过REST API提交作业
您有3个选项,答案是 - 自己检查;)这取决于您的项目和要求。两个主要选项:
应该对你有好处,你必须检查在项目中使用哪些更容易和更好
您可以通过不同方式使用应用程序中的Spark,具体取决于您的需求和喜好。
SparkLauncher是来自spark-launcher
工件的类。它用于启动已准备好的Spark作业,就像Spark Submit。
典型用法是:
1)使用Spark作业构建项目,并将JAR文件复制到所有节点 2)从客户端应用程序,即Web应用程序,创建指向准备好的JAR文件的SparkLauncher
SparkAppHandle handle = new SparkLauncher()
.setSparkHome(SPARK_HOME)
.setJavaHome(JAVA_HOME)
.setAppResource(pathToJARFile)
.setMainClass(MainClassFromJarWithJob)
.setMaster("MasterAddress
.startApplication();
// or: .launch().waitFor()
startApplication
创建SparkAppHandle,允许您添加侦听器并停止应用程序。它还为getAppId
提供了可能性。
SparkLauncher应该与Spark REST API一起使用。您可以查询http://driverNode:4040/api/v1/applications/*ResultFromGetAppId*/jobs
,您将获得有关应用程序当前状态的信息。
还可以通过RESTful API直接提交Spark作业。用法与SparkLauncher
非常相似,但它以纯REST的方式完成。
示例请求 - 本文的学分:
curl -X POST http://spark-master-host:6066/v1/submissions/create --header "Content-Type:application/json;charset=UTF-8" --data '{
"action" : "CreateSubmissionRequest",
"appArgs" : [ "myAppArgument1" ],
"appResource" : "hdfs:///filepath/spark-job-1.0.jar",
"clientSparkVersion" : "1.5.0",
"environmentVariables" : {
"SPARK_ENV_LOADED" : "1"
},
"mainClass" : "spark.ExampleJobInPreparedJar",
"sparkProperties" : {
"spark.jars" : "hdfs:///filepath/spark-job-1.0.jar",
"spark.driver.supervise" : "false",
"spark.app.name" : "ExampleJobInPreparedJar",
"spark.eventLog.enabled": "true",
"spark.submit.deployMode" : "cluster",
"spark.master" : "spark://spark-cluster-ip:6066"
}
}'
此命令将ExampleJobInPreparedJar
类中的作业提交给具有给定Spark Master的群集。在回复中,您将拥有submissionId
字段,这将有助于检查应用程序的状态 - 只需调用其他服务:curl http://spark-cluster-ip:6066/v1/submissions/status/submissionIdFromResponse
。这就是它,仅仅是代码
Livy REST Server和Spark Job Server是RESTful应用程序,允许您通过RESTful Web Service提交作业。这两者与Spark的REST界面之间的一个主要区别是,Livy和SJS并不需要先准备好工作并打包到JAR文件。您只需提交将在Spark中执行的代码。
用法非常简单。代码来自Livy存储库,但有一些削减以提高可读性
1)案例1:提交作业,放在本地机器
// creating client
LivyClient client = new LivyClientBuilder()
.setURI(new URI(livyUrl))
.build();
try {
// sending and submitting JAR file
client.uploadJar(new File(piJar)).get();
// PiJob is a class that implements Livy's Job
double pi = client.submit(new PiJob(samples)).get();
} finally {
client.stop(true);
}
2)案例2:动态创造和执行作业
// example in Python. Data contains code in Scala, that will be executed in Spark
data = {
'code': textwrap.dedent("""\
val NUM_SAMPLES = 100000;
val count = sc.parallelize(1 to NUM_SAMPLES).map { i =>
val x = Math.random();
val y = Math.random();
if (x*x + y*y < 1) 1 else 0
}.reduce(_ + _);
println(\"Pi is roughly \" + 4.0 * count / NUM_SAMPLES)
""")
}
r = requests.post(statements_url, data=json.dumps(data), headers=headers)
pprint.pprint(r.json())
如您所见,可以使用预编译的作业和对Spark的即席查询。
另一个Spark as a Service应用程序。 Mist非常简单,类似于Livy和Spark Job Server。
用法非常相似
1)创建工作文件:
import io.hydrosphere.mist.MistJob
object MyCoolMistJob extends MistJob {
def doStuff(parameters: Map[String, Any]): Map[String, Any] = {
val rdd = context.parallelize()
...
return result.asInstance[Map[String, Any]]
}
}
2)将作业文件打包到JAR中 3)向Mist发送请求:
curl --header "Content-Type: application/json" -X POST http://mist_http_host:mist_http_port/jobs --data '{"path": "/path_to_jar/mist_examples.jar", "className": "SimpleContext$", "parameters": {"digits": [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]}, "namespace": "foo"}'
我可以在Mist中看到的一个强大功能是它通过MQTT为流媒体作业提供开箱即用的支持。
Apache Toree是为了实现Spark的简单交互式分析。它不需要构建任何JAR。它通过IPython协议工作,但不仅支持Python。
目前文档侧重于Jupyter笔记本支持,但也有REST风格的API。
我列出了几个选项:
所有这些都适用于不同的用例。我可以区分几个类别:
SparkLauncher非常简单,是Spark项目的一部分。您正在使用普通代码编写作业配置,因此它比JSON对象更容易构建。
对于完全RESTful风格的提交,请考虑Spark REST API,Livy,SJS和Mist。其中三个是稳定的项目,有一些生产用例。 REST API还要求预先打包作业,而Livy和SJS不需要。但是请记住,Spark REST API在每个Spark发行版中都是默认的,而Livy / SJS则不是。我不太了解Mist,但是 - 过了一段时间 - 它应该是整合所有类型Spark工作的非常好的工具。
Toree专注于互动工作。它仍在孵化,但即使是现在你也可以检查它的可能性。
为什么在内置REST API时使用自定义的附加REST服务?像Livy这样的SaaS是Spark的一个切入点。它管理Spark上下文,并且只在一个节点上,而不是在群集之外的其他地方。它们还支持交互式分析。 Apache Zeppelin使用Livy将用户代码提交给Spark
答案 1 :(得分:6)
这里有SparkLauncherT.Gawęda提到的一个例子:
SparkAppHandle handle = new SparkLauncher()
.setSparkHome(SPARK_HOME)
.setJavaHome(JAVA_HOME)
.setAppResource(SPARK_JOB_JAR_PATH)
.setMainClass(SPARK_JOB_MAIN_CLASS)
.addAppArgs("arg1", "arg2")
.setMaster("yarn-cluster")
.setConf("spark.dynamicAllocation.enabled", "true")
.startApplication();
Here您可以在单个项目中找到捆绑了Spark作业的Java Web应用程序示例。通过SparkLauncher
,您可以获得SparkAppHandle
,以获取有关工作状态的信息。如果您需要进度状态,可以使用Spark rest-api:
http://driverHost:4040/api/v1/applications/[app-id]/jobs
SparkLauncher
所需的唯一依赖项:
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-launcher_2.10</artifactId>
<version>2.0.1</version>
</dependency>
答案 2 :(得分:0)
您可以使用PredictionIO PredictionIO,面向开发人员和ML工程师的机器学习服务器。 https://github.com/apache/predictionio
答案 3 :(得分:0)
我觉得你可以试试SparkSQL JDBC的方式。
首先,您应该使用命令 ./dev/make-distribution.sh --name custom-spark --tgz -PR -Phive -Phive-thriftserver -Pyarn -Dhadoop.version=3.2.0
克隆 spark 源代码和 rebuild,不同的 jar 版本可能会导致兼容运行时错误。
第二,安装上述包并启动thriftserver sbin/start-thriftserver.sh --master yarn --deploy-mode client
。
然后可以使用beeline来测试JDBC是否工作正常。