假设我使用hadoop map reduce处理了n个文件,假设它们很大,远远超出了块大小,而且只有几百个。现在我想处理这些文件中的每一个,让我们假设计算单词的例子。
我的问题是:创建一个map reduce作业,其输入是一个包含每个文件路径的文本文件,而不是将每个文件直接发送到map函数,即连接所有文件并将其推入不同的Map器[edit],两者之间有什么区别。
这两种方法都有效吗?它们有什么缺点吗?
感谢您的及时回答,我已经详细描述了我的问题,因为我的抽象可能遗漏了几个重要的主题:
在我的应用程序中hadoophdfs上有n个小文件,我只需要处理每个文件。因此,我使用map函数将python脚本应用于每个文件(实际上是图像[我已经查看了所有hadoop图像处理链接]),我知道小文件的问题,典型的建议是将较小的文件分组,这样我们就避免了移动文件的开销(基本建议是使用序列文件或创建自己的数据结构,如hipi)。
这让我想知道,难道我们不能告诉每个Map绘制者寻找本地文件并对其进行操作吗?
我还没有找到一个解决这个问题的方法,这就是为什么我在寻找发送路径的文件到每个Map器或文件本身。
为每个图像集合创建一个路径名列表似乎是可以的,但是正如在注解中提到的,我丢失了datalocality属性。
现在,当我查看hadoop流接口时,它提到不同的部分是基于stdin和stdout进行通信的,通常用于文本文件。这就是我感到困惑的地方,如果我只是发送一个路径名列表,这不应该是一个问题,因为每个Map程序只会试图找到它分配的图像集合。但是当我看字数计算的例子时,输入的是一个文件,然后它在Map器中被拆分,所以那时候我很困惑,我是否应该将图像连接到组中,然后像文本文档一样将这些连接的组发送到不同的Map器,或者我是否应该将图像连接起来,让它们留在Map器中hadoop hdfs,然后将路径传递给Map器。。。我希望这有意义。。。也许我已经完全离开这里了。。。
再次感谢!
3条答案
按热度按时间f8rj6qna1#
两者都有效。但后者会带来额外的开销,性能也会下降,因为您所说的是将所有文件连接到一个文件中,并只将其提供给一个Map器。这样做会违背hadoop最基本的原则之一,
parallelism
. 并行是hadoop如此高效的原因。仅供参考,如果你真的需要这样做,你必须设置
isSplittable
在你的生活中弄虚作假InputFormat
类,否则框架将拆分文件(基于您的输入格式)。至于输入路径,您只需要给出输入目录的路径。此目录中的每个文件都将在无需人工干预的情况下进行处理。
hth公司
针对您的编辑:
我想你有点误解了。你不必担心本地化。hadoop会解决这个问题。您只需运行作业,数据将在其所在的节点上进行处理。文件的大小与此无关。你不必告诉Map绘制者任何事情。过程如下:
你把工作交给jt。jt指示在节点上运行的tt启动Map程序,该节点具有作业所需的数据块。如果插槽被其他进程占用,那么在具有数据块的其他节点上也会发生同样的事情。
cx6n0qe32#
如前所述,如果您在单个Map器中处理整个连接文件,则会出现瓶颈。
这不会是一个问题,因为您提供了连接文件作为hadoop的输入。因为,所形成的大文件显然将分布在hdfs中(我假设您使用的是hdfs),并且将由多个Map器和还原器同时处理。
8iwquhpp3#
我的问题是:创建一个map reduce作业(其输入是一个文本文件,其中包含每个文件的路径)与将每个文件直接发送到map函数(即连接所有文件并将其推入单个Map器)之间有什么区别。
通过在文本文件中列出文件路径并(我假设)在Map器中手动打开它们,您将破坏数据位置(hadoop将尝试在数据所在的位置运行Map器代码,而不是将数据移动到代码执行的位置)。对于1000个文件,这也可能由一个mapper示例处理(我认为1000行文本应该小于块大小)。
如果您先连接所有文件,然后将其用作输入,这通常会降低效率,主要是因为您将所有文件复制到单个节点(以连接它们),然后将数据作为单个文件推回到hdfs。这甚至在您在Map器中再次处理文件之前(或者更多,取决于您的输入格式拆分/压缩编解码器的可拆分性)。
如果您要多次处理这个连接的文件,并且每个文件都小于块大小,那么将它们合并到单个文件可能是有益的,但是您已经注意到每个文件都大于默认块大小。
您希望所有文件都通过一个Map器(这听起来像是您试图通过执行这两个选项来实现的)有什么特别的原因吗。