如何使用Spark创建MapFile并访问它?

时间:2015-04-18 09:08:52

标签: hadoop apache-spark hdfs mapr

我正在尝试从Spark RDD创建MapFile,但找不到足够的信息。以下是我到目前为止的步骤:

我开始时,

rdd.saveAsNewAPIHadoopFile(....MapFileOutputFormat.class)

由于必须对MapFiles进行排序,因此抛出异常

。 所以我修改为:

rdd.sortByKey().saveAsNewAPIHadoopFile(....MapFileOutputFormat.class)

工作正常,我的MapFile已创建。所以下一步是访问该文件。使用创建parts的目录名失败,说它无法找到data文件。回到Google,我发现为了访问我需要使用的MapFile部分:

Object ret = new Object();//My actual WritableComparable impl
Reader[] readers = MapFileOutputFormat.getReaders(new Path(file), new Configuration());
Partitioner<K,V> p = new HashPartitioner<>();
Writable e = MapFileOutputFormat.getEntry(readers, p key, ret);

天真地,我忽略了HashPartioner位,并期望这会找到我的参赛作品,但没有运气。所以我的下一步是循环读者并做get(..)。这个解决方案确实有效,但由于128个任务创建了128个part文件,因此文件非常慢。

所以我调查了HashPartitioner的重要性,并发现它在内部使用它来识别要使用的读取器,但似乎Spark没有使用相同的分区逻辑。所以我修改为:

rdd.partitionBy(new org.apache.spark.HashPartitioner(128)).sortByKey().saveAsNewAPIHadoopFile(....MapFileOutputFormat.class)

但是2 HashPartioner再次不匹配。所以问题部分......

  • 有没有办法有效地组合MapFiles(因为这会忽略分区逻辑)?
  • MapFileOutputFormat.getReaders(new Path(file), new Configuration());非常慢。我可以更多地识别读者吗? 有效?
  • 我使用MapR-FS作为底层DFS。这会使用相同的HashParitioner实现吗?
  • 有没有办法避免重新分区,还是应该在整个文件中对数据进行排序? (与在分区内排序相反)
  • 我也得到例外_SUCCESS/data does not exist。我是否需要手动删除此文件?

非常感谢任何关于此的链接。

PS。如果条目已排序,那么如何使用HashPartitioner找到正确的Reader?这意味着数据partsHash Partitioned,然后按键排序。所以我也试过rdd.repartiotionAndSortWithinPartitions(new HashPartitioner(280)),但又没有任何运气。

1 个答案:

答案 0 :(得分:3)

深入研究这个问题,我发现Spark HashPartitioner和Hadoop HashPartitioner有不同的逻辑。

所以我尝试和运作的“蛮力”解决方案如下。

使用rdd.repartitionAndSortWithinPArtitions(new org.apache.aprk.HashPartitioner(num_of_parititions)).saveAsNewAPIHadoopFile(....MapFileOutputFormat.class);

保存MapFile

查找使用:

  • Reader [] readers = MapFileOutputFormat.getReaders(new Path(file),new Configuration());
  • org.apache.aprk.HashPartitioner p = new org.apache.aprk.HashPartitioner(readers.length);
  • 读者[p.getPartition(键)]得到(键,缬氨酸);

这是“脏”的,因为MapFile访问现在绑定到Spark分区器而不是直观的Hadoop HashPartitioner。我可以实现一个使用Hadoop HashPartitioner来改进的Spark分区器。

这也没有解决访问相对大量减速器的问题。我可以通过从分区程序生成文件部件号来使这甚至“更脏”,但我正在寻找一个干净的解决方案,所以如果有更好的方法解决这个问题,请发布。