如何将Spark上下文传递给foreach中的函数

时间:2016-01-24 16:04:42

标签: scala apache-spark

我需要将SparkContext传递给我的函数,请建议我如何为以下场景执行此操作。

我有一个序列,每个元素指的是我们从中获取RDD并处理它们的特定数据源。我已经定义了一个函数,它接受了spark上下文和数据源并做了必要的事情。我当前正在使用while循环。但是,我想用foreach或map来做,所以我可以暗示并行处理。我需要为函数激发上下文,但是如何从foreach中传递它。?

只是一个SAMPLE代码,因为我无法呈现实际代码:

import org.apache.spark.SparkConf
import org.apache.spark.SparkContext
import org.apache.spark.sql.SQLContext

object RoughWork {
  def main(args: Array[String]) {

    val str = "Hello,hw:How,sr:are,ws:You,re";
    val conf = new SparkConf
    conf.setMaster("local");
    conf.setAppName("app1");
    val sc = new SparkContext(conf);
    val sqlContext = new SQLContext(sc);

    val rdd = sc.parallelize(str.split(":"))
    rdd.map(x => {println("==>"+x);passTest(sc, x)}).collect();

  }

  def passTest(context: SparkContext, input: String) {
    val rdd1 = context.parallelize(input.split(","));
    rdd1.foreach(println)
  }
}

1 个答案:

答案 0 :(得分:2)

你不能像那样传递SparkContext。 passTest将在/执行程序上运行,而SparkContext在驱动程序上运行。

如果我必须进行这样的双重拆分,一种方法是使用flatMap

rdd
  .zipWithIndex
  .flatMap(l => {
    val parts = l._1.split(",");
    List.fill(parts.length)(l._2) zip parts})
  .countByKey

可能有更漂亮的方法,但基本上这个想法是你可以使用zipWithIndex来跟踪项目来自哪一行,然后使用键值对RDD方法处理你的数据。

如果您有一个以上的密钥,或者通常只有更多结构化数据,您可以考虑将Spark SQL与DataFrames(或最新版本的DataSet)和explode而不是flatMap一起使用。< / p>