在我的应用程序中,我使用并行化方法将数组保存到文件中。
代码如下:
val sourceRDD = sc.textFile(inputPath + "/source")
val destinationRDD = sc.textFile(inputPath + "/destination")
val source_primary_key = sourceRDD.map(rec => (rec.split(",")(0).toInt, rec))
val destination_primary_key = destinationRDD.map(rec => (rec.split(",")(0).toInt, rec))
val extra_in_source = source_primary_key.subtractByKey(destination_primary_key)
val extra_in_destination = destination_primary_key.subtractByKey(source_primary_key)
val source_subtract = source_primary_key.subtract(destination_primary_key)
val Destination_subtract = destination_primary_key.subtract(source_primary_key)
val exact_bestmatch_src = source_subtract.subtractByKey(extra_in_source).sortByKey(true).map(rec => (rec._2))
val exact_bestmatch_Dest = Destination_subtract.subtractByKey(extra_in_destination).sortByKey(true).map(rec => (rec._2))
val exact_bestmatch_src_p = exact_bestmatch_src.map(rec => (rec.split(",")(0).toInt))
val primary_key_distinct = exact_bestmatch_src_p.distinct.toArray()
for (i <- primary_key_distinct) {
var dummyVar: String = ""
val src = exact_bestmatch_src.filter(line => line.split(",")(0).toInt.equals(i))
var dest = exact_bestmatch_Dest.filter(line => line.split(",")(0).toInt.equals(i)).toArray
for (print1 <- src) {
var sourceArr: Array[String] = print1.split(",")
var exactbestMatchCounter: Int = 0
var index: Array[Int] = new Array[Int](1)
println(print1 + "source")
for (print2 <- dest) {
var bestMatchCounter = 0
var i: Int = 0
println(print1 + "source + destination" + print2)
for (i <- 0 until sourceArr.length) {
if (print1.split(",")(i).equals(print2.split(",")(i))) {
bestMatchCounter += 1
}
}
if (exactbestMatchCounter < bestMatchCounter) {
exactbestMatchCounter = bestMatchCounter
dummyVar = print2
index +:= exactbestMatchCounter //9,8,9
}
}
var z = index.zipWithIndex.maxBy(_._1)._2
if (exactbestMatchCounter >= 0) {
var samparr: Array[String] = new Array[String](4)
samparr +:= print1 + " BEST_MATCH " + dummyVar
var deletedest: Array[String] = new Array[String](1)
deletedest = dest.take(z) ++ dest.drop(1)
dest = deletedest
val myFile = sc.parallelize((samparr)).saveAsTextFile(outputPath)
我使用了parallelize方法,我甚至尝试使用以下方法将其保存为文件
val myFile = sc.textFile(samparr.toString())
val finalRdd = myFile
finalRdd.coalesce(1).saveAsTextFile(outputPath)
但它不断抛出错误:
线程“main”中的异常org.apache.spark.SparkException:任务不可序列化
答案 0 :(得分:0)
您不能将RDD视为本地集合。针对它的所有操作都发生在分布式集群上。要运行,您在该rdd中运行的所有函数都必须是可序列化的。
该行
for (print1 <- src) {
在这里迭代RDD src,循环内的所有内容都必须序列化,因为它将在执行程序上运行。
然而,在内部,您仍然在该循环中尝试运行sc.parallelize(
。 SparkContext不可序列化。使用rdds和sparkcontext是您在驱动程序上执行的操作,而不能在RDD操作中执行。
我完全确定你要完成什么,但它看起来像某种手工编码的连接操作与源和目标。你不能像在本地集合中那样使用rdds中的循环。利用apis map,join,groupby等创建最终的rdd,然后保存。
如果你绝对觉得你必须像这样在rdd上使用foreach循环,那么就不能使用sc.parallelize().saveAsTextFile()
而是使用hadoop文件api打开输出流并手动将数组写入文件。
答案 1 :(得分:0)
最后这段代码帮助我将数组保存到文件中。
new PrintWriter(outputPath) { write(array.mkString(" ")); close }