在Spark中反转一对多转换

时间:2017-10-12 11:08:25

标签: apache-spark dataframe

我有一个像

这样的数据集
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;文件。

1 个答案:

答案 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"), ",")))