2

假设我有 N 个文件要使用 hadoop map-reduce 处理,假设它们很大,远远超出块大小,并且只有几百个。现在我想处理这些文件中的每一个,让我们假设字数统计示例。

我的问题是:创建一个输入是包含每个文件路径的文本文件的map-reduce作业与将每个文件直接发送到map函数(即连接所有文件并推送它们)有什么区别进入不同的映射器 [编辑]

这些都是有效的方法吗?他们有什么缺点吗?

感谢您的及时回答,因为我的抽象可能遗漏了一些重要主题,所以我已经详细描述了我的问题:

我的应用程序中的 Hadoop HDFS 上有 N 个小文件,我只需要处理每个文件。因此,我使用 map 函数将 python 脚本应用于每个文件(实际上是图像 [我已经查看了那里的所有 hadoop 图像处理链接]),我知道小文件问题,典型的建议是将较小的文件分组,这样我们就可以避免移动文件的开销(基本建议使用序列文件或创建自己的数据结构,如 HIPI 的情况)。

这让我想知道我们不能告诉每个映射器查找他本地的文件并对其进行操作吗?

我还没有找到解决该问题的方法,这就是为什么我正在考虑将文件路径发送到每个映射器或它自己的文件。

为每个图像集合创建一个路径名列表似乎没问题,但正如评论中提到的,我失去了数据局部性属性。

现在,当我查看 hadoop 流接口时,它提到不同的部分基于通常用于文本文件的标准输入和标准输出进行通信。这就是我感到困惑的地方,如果我只是发送一个路径名列表,这不应该是一个问题,因为每个映射器只会尝试找到它分配的图像集合。但是当我查看字数统计示例时,输入是文件,然后在映射器中拆分,所以我很困惑是否应该将图像连接成组,然后像文本文档一样将这些连接的组发送到不同的映射器,或者如果我应该将图像连接起来,将它们留在hadoop HDFS中,然后将它们的路径传递给映射器......我希望这是有道理的......也许我完全离开了这里......

再次感谢!

4

3 回答 3

2

两者都是有效的。但是后者会产生额外的开销并且性能会下降,因为您正在谈论将所有文件连接成一个并将其提供给仅 1 个映射器。这样做会违背 Hadoop 最基本的原则之一,parallelism. 并行性是 Hadoop 如此高效的原因。

仅供参考,如果你真的需要这样做,你必须isSplittable在你的类中设置为 false InputFormat,否则框架将分割文件(基于你的 InputFormat)。

就输入路径而言,您只需要给出输入目录的路径即可。此目录中的每个文件都将在没有人为干预的情况下进行处理。

高温高压


回应您的编辑:

我想你有点误解了这一点。您不必担心本地化。Hadoop 负责这一点。您只需要运行您的作业,数据就会在它所在的节点上进行处理。文件的大小与它无关。你不必告诉映射器任何东西。过程是这样的:

您将工作提交给 JT。JT 指示在具有作业所需数据块的节点上运行的 TT 启动映射器。如果插槽被其他进程占用,那么同样的事情会发生在其他具有数据块的节点上。

于 2013-07-02T05:45:30.173 回答
0

我的问题是:创建一个输入是包含每个文件路径的文本文件的map-reduce作业与将每个文件直接发送到map函数(即连接所有文件并推送它们)有什么区别到单个映射器中。

通过在文本文件中列出文件路径并(我假设)在映射器中手动打开它们,您将击败数据局部性(即 hadoop 将尝试在数据所在的位置运行映射器代码,而不是移动数据到您的代码执行的位置。对于 1000 个文件,这也可能由单个映射器实例处理(我想 1000 行文本应该小于您的块大小)。

如果您首先连接所有文件然后用作输入,这通常效率较低,主要是因为您将所有文件复制到单个节点(以连接它们),然后将数据作为单个推回 HDFS文件。这甚至在您在映射器中再次处理文件之前(或更多取决于您的输入格式拆分/压缩编解码器的可拆分性)。

如果您要多次处理这个连接的文件,并且每个文件都小于块大小,那么将它们合并到一个文件可能是有益的,但您已经注意到每个文件都大于默认块大小。

您是否有特别的原因希望所有文件都流经一个映射器(这听起来像是您试图通过执行这两个选项来实现的)。

于 2013-07-02T10:39:45.243 回答
0

如前所述,如果您在单个映射器中处理整个连接文件,则会出现瓶颈。

如果您将连接的文件作为输入提供给 Hadoop,这将不是问题。因为,形成的大文件显然会分布在 HDFS 中(我假设您使用的是 HDFS),并且将由多个 Mapper 和 reducer 同时处理。

于 2013-07-02T06:30:20.503 回答