通常在从List创建RDD时,您可以使用SparkContext.parallelize
方法,但不能在Task中使用spark上下文,因为它不可序列化。我需要从任务中的字符串列表中创建RDD。有没有办法做到这一点?
我尝试在任务中创建一个新的SparkContext,但是它给了我一个错误,即不支持同一个JVM中的多个spark上下文,我需要设置spark.driver.allowMultipleContexts = true
。根据Apache用户组,the google design site which uses paper ripple but not polymer
答案 0 :(得分:4)
就我而言,这是不可能的,这不是序列化或支持多个Spark上下文的问题。一个基本的限制是核心Spark架构。由于Spark上下文由驱动程序维护,并且在从任务内部创建RDD的worker上执行任务,因此需要将更改从worker更改为驱动程序。我不是说这在技术上是不可能的,但整个想法似乎相当麻烦。
从内部任务创建Spark上下文看起来更糟糕。首先,它意味着上下文是在工人身上创建的,出于所有实际目的,这些上下文不会相互通信。每个工作人员都会获得自己的上下文,该上下文只能在给定工作人员可访问的数据上运行。最后保留工作者状态绝对不是合同的一部分,因此在任务完成后,任何上下文创建都应该简单地进行垃圾收集。
如果无法使用多个作业处理问题,您可以尝试使用mapPartitions
,如下所示:
val rdd = sc.parallelize(1 to 100)
val tmp = rdd.mapPartitions(iter => {
val results = Map(
"odd" -> scala.collection.mutable.ArrayBuffer.empty[Int],
"even" -> scala.collection.mutable.ArrayBuffer.empty[Int]
)
for(i <- iter) {
if (i % 2 != 0) results("odd") += i
else results("even") += i
}
Iterator(results)
})
val odd = tmp.flatMap(_("odd"))
val even = tmp.flatMap(_("even"))