我有一个像
这样的数据集a1<tab>b1,b2,b3,b4
a2<tab>b1,b2,b3
........
........
........
aN<tab>bX,bY,bZ
我想将其转换为相反的方式,即
b1 -> a1
b1 -> aY
....
....
b2 -> aX
b2 -> aY
b2 -> aZ
....
....
bN -> a1
bN -> aY
如何在不堵塞堆空间的情况下实现相同目标?
我已经使用mapPartitions进行分区转换以避免shuffle,然后使用distcp按键进行合并。但是当一个键的值的数量很多时,火花作业似乎失败了。
相关的代码段如下:
val res_rdd=rdd.mapPartitions{
iterator => {
iterator.toList
.map(f => (f.split("\t")(1).split(","),f.split("\t")(0))).flatMap(k => k._1.map(y=> (y,k._2)))
.iterator
}
}
import sqlContext.implicits._
val df=res_rdd.toDF("newKey","newValue")
df.write.partitionBy("newKey").text(outputPath)
最终结果需要拥有所有&#34; newValue&#34; s&#34; newKey&#34;文件。
答案 0 :(得分:2)
请勿转换为List
iterator.toList
没有理由把所有东西都留在记忆中。
mapPartitions
没有任何收获,最好一直使用Dataset
:
import org.apache.spark.sql.functions._
spark.read.option("delimiter", "\t").csv(path).toDF("key", "value")
.withColumn("value", explode(split(col("value"), ",")))