将RDD的前k值写入Spark

时间:2015-12-07 21:33:05

标签: java apache-spark rdd

我想从Tuple2对象的RDD中提取前k个值并将它们写入文件。 我一直在尝试的方法是使用top函数并将其传递给Comparator对象。这将返回一个Tuple2对象列表。

现在我可以在单个节点上合并此列表并迭代此列表并使用FileWriter将值打印到文件中。 但这将导致单个文件。我希望每个reducer都有几个文件。

有什么办法可以在List而不是RDD上使用saveAsTextFile? 我正在使用Spark 1.5.1和Java。

Comparator<Tuple2<String, Double>> tc = new TupleComparator();

    List<Tuple2<String,Double>> output = ranks.coalesce(1,true).top(topK,tc);

  /*  for (Tuple2<String,Double> tuple : output){
        System.out.println(tuple._1() + " has rank: " + tuple._2() + ".");
    }*/
    BufferedWriter writer = new BufferedWriter(new FileWriter(args[2],false));
    int i=1;
    for(Tuple2<String,Double> tuple: output) {
      writer.write(i + " " + tuple._1 + " " + tuple._2);
      writer.newLine();
      i++;
    }
    writer.close();

1 个答案:

答案 0 :(得分:0)

您可以使用foreachPartition,并在每个分区上使用FileWriter(或我的代码示例中的PrintWriter),如下所示:

import scala.util.Random

sc.parallelize( {1 to 12}.zipWithIndex, 4)
      .foreachPartition( part => 
            printToFile(new File(s"partition_${Random.nextInt}"))  
            {p=> part.foreach(p.println)}
       )

我使用以下内容输出列表:

import java.io._

  //  usage:  printToFile(new File("filename")) { p => myCollection.foreach(p.println) }

def printToFile(f: java.io.File)(op: java.io.PrintWriter => Unit) { 
        val p = new java.io.PrintWriter(f); 
        try { op(p) } finally { p.close() } 
}