我需要将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)
}
}
答案 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>