1

我目前正在尝试编写一个 map-reduce 作业,其中输入数据不在 HDFS 中,并且基本上无法加载到 HDFS 中,因为使用数据的程序不能使用来自 HDFS 的数据,并且有太多可以将其复制到 HDFS 中,至少每个节点 1TB。

所以我在集群中的 4 个节点上都有 4 个目录。理想情况下,我希望我的映射器只接收这 4 个本地目录的路径并读取它们,使用类似 file:///var/mydata/... 的东西,然后 1 个映射器可以处理每个目录。即总共16个映射器。

但是,为了能够做到这一点,我需要确保每个节点正好有 4 个映射器,并且正好有 4 个映射器被分配到该机器的本地路径。这些路径是静态的,因此可以硬编码到我的文件输入格式和记录读取器中,但是我如何保证给定的拆分最终出现在具有已知主机名的给定节点上。如果它在 HDFS 中,我可以使用 FileInputFormat 的变体设置 isSplittable 为 false,hadoop 会处理它,但由于所有数据都是本地的,这会导致问题。

基本上,我想要的是能够在集群中的每个节点上抓取一次本地目录结构,处理这些目录中的 SSTables 集合并发出行(在映射器上),并将结果(在 reduce 步骤中)减少到HDFS 用于进一步的批量处理。

我注意到 inputSplits 提供了一个 getLocations 函数,但我相信这并不能保证执行的位置,只会优化它,并且如果我尝试在每个映射器中使用 file:///some_path 我需要确保确切的位置,否则我可能会结束重复阅读一些目录,而其他根本不阅读。

任何帮助将不胜感激。

4

1 回答 1

0

我看到有三种方法可以做到这一点。

1.) 只需将数据加载到 HDFS 中,您不想这样做。但值得一试,因为它将对未来的处理有用

2.) 您可以使用 NLineInputFormat。使用每个节点中输入文件的 URL 创建四个不同的文件。

file://192.168.2.3/usr/rags/data/DFile1.xyz
.......

您将这些文件加载​​到 HDFS 并在这些文件上编写程序以使用这些 URL 访问数据数据并处理您的数据。如果您将 NLineInputFormat 与 1 行一起使用。您将处理 16 个映射器,每个映射处理一个专有文件。这里唯一的问题,一个节点上的数据很有可能在另一个节点上处理,但是不会有任何重复处理

3.) 您可以进一步优化上述方法,分别加载上述四个带有 URL 的文件。在加载这些文件中的任何一个时,您可以删除其他三个节点,以确保文件准确地转到本地存在数据文件的节点。加载时选择复制为 1,以便不复制块。这个过程会极大地增加启动的地图处理本地文件的概率。

干杯抹布

于 2013-03-27T12:55:39.750 回答