【问题标题】:How to run Scala script using spark-submit (similarly to Python script)?如何使用 spark-submit 运行 Scala 脚本(类似于 Python 脚本)?
【发布时间】:2017-06-03 17:31:52
【问题描述】:

我尝试使用 Spark 执行一个简单的 Scala 脚本,如 Spark Quick Start Tutorial 中所述。我没有麻烦执行以下 Python 代码:

"""SimpleApp.py"""
from pyspark import SparkContext

logFile = "tmp.txt"  # Should be some file on your system
sc = SparkContext("local", "Simple App")
logData = sc.textFile(logFile).cache()

numAs = logData.filter(lambda s: 'a' in s).count()
numBs = logData.filter(lambda s: 'b' in s).count()

print "Lines with a: %i, lines with b: %i" % (numAs, numBs)

我使用以下命令执行此代码:

/home/aaa/spark/spark-2.1.0-bin-hadoop2.7/bin/spark-submit hello_world.py

但是,如果我尝试使用 Scala 做同样的事情,我就会遇到技术问题。更详细地说,我尝试执行的代码是:

* SimpleApp.scala */
import org.apache.spark.SparkContext
import org.apache.spark.SparkContext._
import org.apache.spark.SparkConf

object SimpleApp {
  def main(args: Array[String]) {
    val logFile = "tmp.txt" // Should be some file on your system
    val conf = new SparkConf().setAppName("Simple Application")
    val sc = new SparkContext(conf)
    val logData = sc.textFile(logFile, 2).cache()
    val numAs = logData.filter(line => line.contains("a")).count()
    val numBs = logData.filter(line => line.contains("b")).count()
    println("Lines with a: %s, Lines with b: %s".format(numAs, numBs))
  }
}

我尝试通过以下方式执行它:

/home/aaa/spark/spark-2.1.0-bin-hadoop2.7/bin/spark-submit hello_world.scala

结果我收到以下错误消息:

Error: Cannot load main class from JAR file

有人知道我做错了什么吗?

【问题讨论】:

  • 在终端(命令行)中导航到 scala 文件所在的文件夹。然后运行“scalac YouClassName.scala”。最后通过运行命令执行它:“scala YourClassName”。顺便说一句,您需要在这些步骤之前安装 Scala :)
  • from JAR file 在消息中是正确的,所以这就是你做错了
  • @AlexFruzenshtein,如果我执行scalac hellow_world.scala,我会收到错误消息error: object apache is not a member of package org

标签: scala apache-spark


【解决方案1】:

我想向@JacekLaskowski 添加一个我有时用于 POC 或测试目的的替代解决方案。

这将是使用spark-shell 内部的script.scala:load

:load /path/to/script.scala

您不需要定义SparkContext/SparkSession,因为脚本将使用在 REPL 范围内定义的变量。

您也不需要将代码包装在 Scala 对象中。

PS:我认为这更像是一种 hack,而不是用于生产目的。

【讨论】:

  • 另外,spark-shell 可以采用“-i file.scala”参数,其中 file.scala 的内容在 REPL 中进行评估,就像输入或 :loaded 然后 REPL 退出一样。
  • @Garren 这不是唯一的方法,但我不想提供更多这样的“黑客”。 (这是坏习惯)
  • 虽然我同意这种风格绝对不应该用于生产应用程序,但这是一种快速原型化的绝妙方式,因此在假设它们会形成坏的情况下,在推广“黑客”的基础上省略一个有效的策略习惯是虚伪的。
  • @Garren 你可能对我的假设是正确的,但我完全同意它是快速原型化的绝妙方法,这就是我使用它们的原因。我稍后会更新我的答案。
  • 如果脚本被包装到Scala对象的main方法中,那么可以通过[object name].main()执行它
【解决方案2】:

使用spark-submit --help 了解选项和参数。

$ ./bin/spark-submit --help
Usage: spark-submit [options] <app jar | python file> [app arguments]
Usage: spark-submit --kill [submission ID] --master [spark://...]
Usage: spark-submit --status [submission ID] --master [spark://...]
Usage: spark-submit run-example [options] example-class [example args]

正如您在第一个用法中看到的那样,spark-submit 需要 &lt;app jar | python file&gt;

app jar 参数是带有主对象的 Spark 应用程序的 jar(在您的情况下为 SimpleApp)。

您可以使用 sbt 或 maven 构建应用程序 jar,您可以在官方文档的 Self-Contained Applications 中阅读:

假设我们希望使用 Spark API 编写一个独立的应用程序。我们将在 Scala(使用 sbt)、Java(使用 Maven)和 Python 中演示一个简单的应用程序。

在本节后面:

我们可以创建一个包含应用程序代码的 JAR 包,然后使用 spark-submit 脚本运行我们的程序。


附言使用Spark 2.1.1

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    • 1970-01-01
    • 2018-04-22
    • 2018-08-12
    • 1970-01-01
    • 2022-01-05
    相关资源
    最近更新 更多