我正在尝试从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());
非常慢。我可以更多地识别读者吗?
有效?HashParitioner
实现吗?_SUCCESS/data does not exist
。我是否需要手动删除此文件?非常感谢任何关于此的链接。
PS。如果条目已排序,那么如何使用HashPartitioner
找到正确的Reader
?这意味着数据parts
为Hash Partitioned
,然后按键排序。所以我也试过rdd.repartiotionAndSortWithinPartitions(new HashPartitioner(280))
,但又没有任何运气。
答案 0 :(得分:3)
深入研究这个问题,我发现Spark HashPartitioner和Hadoop HashPartitioner有不同的逻辑。
所以我尝试和运作的“蛮力”解决方案如下。
使用rdd.repartitionAndSortWithinPArtitions(new
org.apache.aprk.HashPartitioner(num_of_parititions)).saveAsNewAPIHadoopFile(....MapFileOutputFormat.class);
查找使用:
这是“脏”的,因为MapFile访问现在绑定到Spark分区器而不是直观的Hadoop HashPartitioner。我可以实现一个使用Hadoop HashPartitioner
来改进的Spark分区器。
这也没有解决访问相对大量减速器的问题。我可以通过从分区程序生成文件部件号来使这甚至“更脏”,但我正在寻找一个干净的解决方案,所以如果有更好的方法解决这个问题,请发布。