如何提交在运行时生成的Spark作业?

时间:2017-11-25 00:28:56

标签: scala apache-spark playframework sbt

因此,对于我的用例,我需要在运行时创建并提交Spark流式传输作业。做了一些谷歌搜索,我不认为这是一种简单的方法来执行Spark作业而不首先创建jar文件...

我的想法是对Spark / Scala代码进行类似构建器的抽象,通过注入相关对象在运行时配置它,然后将该抽象转换为实际的原始Scala代码并将其写入磁盘。

然后我会使用ProcessBuilder或其他东西在Scala代码上运行sbt包并以这种方式构建jar。然后我应该能够使用SparkLauncher以及通过运行spark-submit命令再次使用ProcessBuilder以编程方式提交作业。

如果我诚实的话,这一切似乎有点愚蠢。有没有人有更好的想法以编程方式提交工作?

使用SparkLauncher的缺点是,我必须预先包装一个巨大的Spark作业jar,它具有可能执行的所有功能。然后,我可以使用SparkLauncher提交它,并为其提供相关的-D参数,以便在运行时修复特定功能。

2 个答案:

答案 0 :(得分:1)

如何使用例如ProcessBuilder运行类似这样的内容:

echo 'println("hello World")' | spark-shell

我认为不需要先创建罐子。

答案 1 :(得分:1)

我有一个客户端需要一次,什么工作正常是创建一个通用的Spark应用程序,接受可以指定较低级别配置细节的参数,如ML算法。使用该通用Spark应用程序,您可以使用SparkLauncher提交它以供执行(您可以在其中指定主URL和特定于部署的参数)。

实际上,如果您使用的是Spark MLlib以及Spark支持的不同ML算法,那么就可以很容易地从通用Spark应用程序中抽象出来,因为您可以编写一个执行预处理并选择估算器的ML管道(算法)按名称,可能是类名。

您还可以将预处理部分(Spark SQL / ML Transformers)和主ML管道拆分为主要通用Spark应用程序将使用的两个单独的类。

在官方文档中查看Spark MLlib的ML Pipelines

因为你担心......

  

使用SparkLauncher的缺点是我必须预先打包一个巨大的Spark作业jar,它具有它可能做的所有功能。

我怀疑这是一个问题。在没有首先考虑要求的情况下,很难说你的Spark应用程序将会有多大,但是如果它是关于Spark MLlib我肯定ML管道功能会将线条切割到最小。

JANINO

您也可以考虑像Spark SQL在WholeStageCodegenExec和其他物理运营商中那样动态生成代码。

Spark SQL uses Janino compiler for code generation因此,查看Spark的那一部分将向您展示在运行时进行代码编译的另一种(非常低级)方式,这将为您提供最大的灵活性。

缺点是审查或测试代码以生成最终代码可能需要做很多工作,很少有人会帮助你。

说到这个不纯的,非常强制性的Janino编译器世界引发了关于使用无标记final或类似的高阶抽象的思考。 我离题