【问题标题】:Duplicated Spark Context with IntelliJ in Worksheet在工作表中使用 IntelliJ 复制 Spark 上下文
【发布时间】:2017-04-01 14:01:29
【问题描述】:

我在 IntelliJ 中有以下工作表:

import org.apache.spark.sql.SQLContext
import org.apache.spark.{SparkConf, SparkContext}

/** Lazily instantiated singleton instance of SQLContext */
object SQLContextSingleton {
  @transient  private var instance: SQLContext = _
  def getInstance(sparkContext: SparkContext): SQLContext = {
    if (instance == null) {
      instance = new SQLContext(sparkContext)
    }
    instance
  }
}

val conf = new SparkConf().
  setAppName("Scala Wooksheet").
  setMaster("local[*]")
val sc = new SparkContext(conf)
val sqlContext = new SQLContext(sc)
val df = sqlContext.read.json("/Users/someuser/some.json")
df.show

此代码在 REPL 中有效,但似乎只在第一次运行(还有一些其他错误)。以后的每一次,错误都是:

16/04/13 11:04:57 WARN SparkContext: Another SparkContext is being constructed (or threw an exception in its constructor).  This may indicate an error, since only one SparkContext may be running in this JVM (see SPARK-2243). The other SparkContext was created at:
org.apache.spark.SparkContext.<init>(SparkContext.scala:82)

如何找到已经在使用的上下文?

注意:我听到其他人说要使用conf.set("spark.driver.allowMultipleContexts","true"),但这似乎是增加内存使用量的解决方案(如未收集的垃圾)。

有没有更好的办法?

【问题讨论】:

  • 我想如果你在工作表的最后一行添加sc.close(),你会没事的——每次执行都会创建一个 SparkContext 并关闭它,所以不会有多个运行.
  • @TzachZohar -- sc 好像没有 close 方法。
  • 糟糕,意思是stop(),对不起
  • @TzachZohar - 谢谢......我仍然需要确保在到达那一点之前我不会崩溃。可能使用 try /catch / finally。必须有一个更常见或更优雅的解决方案。 (???)
  • 另一个想法......也许问题不在于关闭 SparkContext,而是“如何找到已经打开的 SparkContext?”

标签: scala intellij-idea apache-spark apache-spark-sql


【解决方案1】:

我在 IntelliJ IDEA (CE 2016.3.4) 的 Scala Worksheet 中尝试使用 Spark 执行代码时遇到了同样的问题。

创建重复 Spark 上下文的解决方案是取消选中设置 -> 语言和框架 -> Scala -> 工作表中的“在编译器进程中运行工作表”复选框。我还测试了其他工作表设置,它们对重复创建 Spark 上下文的问题没有影响。

我也没有在工作表中输入sc.stop()。 但我必须在 conf 中设置 master 和 appName 参数才能正常工作。

这是来自 Spark Quick Start 的 SimpleApp.scala 代码的工作表版本

import org.apache.spark.{SparkConf, SparkContext}

val conf = new SparkConf()
conf.setMaster("local[*]")
conf.setAppName("Simple Application")

val sc = new SparkContext(conf)

val logFile = "/opt/spark-latest/README.md"
val logData = sc.textFile(logFile).cache()
val numAs = logData.filter(line => line.contains("a")).count()
val numBs = logData.filter(line => line.contains("b")).count()

println(s"Lines with a: $numAs, Lines with b: $numBs")

我使用指南中相同的 simple.sbt 将依赖项导入 IntelliJ IDEA。

以下是使用 Spark 运行的 Scala 工作表的屏幕截图:

IntelliJ CE 2017.1 更新(REPL 模式下的工作表)

2017.1 Intellij 为 Worksheet 引入了 REPL 模式。我已经在选中“使用 REPL”选项的情况下测试了相同的代码。要运行此模式,您需要在上面描述的工作表设置中选中“在编译器进程中运行工作表”复选框(默认情况下)。

代码在 Worksheet REPL 模式下运行良好。

这里是截图:

【讨论】:

  • 创建重复 Spark 上下文的解决方案是取消选中设置 -> 语言和框架 -> Scala -> 工作表中的“在编译器进程中运行工作表”复选框。这对我有用。另一种方法是创建一个简单的 Scala 对象并将 Spark 代码放入其中。
  • 谢谢@jrook,你为我节省了很多时间(y)
【解决方案2】:

作为detectivebag stated in this git post,您可以通过将工作表切换为仅在“eclipse 兼容模式”下运行来解决此问题:

1) 打开偏好

2) 在 Languages and Frameworks 下选择 scala

3) 在工作表选项卡下取消选中除“使用“eclipse 兼容性”模式'以外的所有内容

【讨论】:

    猜你喜欢
    • 2017-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 2017-07-30
    • 1970-01-01
    相关资源
    最近更新 更多