Hadoop MapReduce:适当的输入文件大小是多少?

11

我的数据集大小为3位数GB甚至1到2位数TB。所以输入文件是一系列的文件,每个文件大约10GB。我的Hadoop中的MapReduce作业处理所有这些文件,然后只生成一个输出文件(其中包含汇总信息)。

我的问题是:

  1. 从Apache来调整Hadoop/MapReduce框架,适合的文件大小是多少?我听说更喜欢较大的文件大小而不是小的文件大小。有任何想法吗?我唯一确定的是,Hadoop默认读取64MB的块。因此,如果文件大小是64MB的倍数,则会非常好。

  2. 目前,我的应用程序将输出文件写入一个文件中。因此,文件大小当然为3位数的gigabit。我想知道如何有效地对文件进行分区。当然,我可以使用某些Unix工具来完成这项工作。但是,直接在Hadoop中执行此操作是否更可取?

感谢您的意见!

P.S.: 我没有压缩文件。输入文件的文件格式为文本/ CSV。


很多问题(请在原问题中回答):您是否正在压缩文件?如果是,使用的压缩类型是什么(gzip、bz2等)?输入文件的文件格式是什么(文本、二进制)? - Chris White
@Chris:我没有压缩文件。输入文件的文件格式是text/csv。谢谢! - Bob
3个回答

7
如果您没有压缩文件,那么hadoop将会处理您的大文件(比如10G),并使用若干个与文件块大小相关联的mapper。假设您的块大小为64M,则将使用大约160个mapper来处理这个10G文件(160*64 ~= 10G)。根据mapper逻辑的CPU密集程度,这可能是一个可以接受的块大小,但如果您发现mapper的执行时间在几分钟内,那么您可能希望增加每个mapper的工作量(通过增加块大小到128、256、512m来实现-实际大小取决于您如何处理数据)。
较大的块大小将减少用于处理10G文件的mapper数量。当然,您可以增加TextInputFormat使用的最小分片大小,但随之而来的问题可能是较低的数据本地性,因为mapper可能会处理2个或更多块,这些块可能不都驻留在该节点上。
至于输出,这取决于您的处理逻辑正在做什么-您是否可以通过引入更多reducer进行分区?这将创建更多的输出文件,但是对于这些文件,您需要什么分区逻辑呢?(默认情况下,它们将按键哈希分区)

通过分区,我指的是将输出文件拆分为几个其他文件,因为我将再次将此输出用作其他MapReduce作业的输入。一个1TB大小的文件会有点糟糕,对吧? - Bob
取决于(与之前类似的问题 - 压缩?输出格式?)。如果您可以使用多个reducer来构建输出文件,那么您将获得更好的吞吐量(在这种情况下,您实际上会获得多个输出文件,但它们可以用于后续作业。一切都取决于是否需要将所有内容发送到单个reducer)。 - Chris White
Mapper的数量不取决于块大小,而取决于输入切片的大小。 - siddhartha jain
@siddharthajain - 默认情况下,FileInputFormat使用文件的块数来确定拆分的数量 - 除非您调整作业参数,或者您的块大小小于默认的最小拆分大小。 - Chris White

5

输入文件的大小:

一种调整方法是查看map任务完成的速度。每个map任务将接收1个文件作为输入,如果它们在30-40秒内完成,则应考虑增加每个文件的大小,以使每个mapper有更多的工作要做。这是因为map任务需要大约30秒的时间来初始化,然后才会开始真正的工作。

此外,这也取决于您的集群可以同时运行多少个map任务。您可以尝试调整文件和块大小,以充分利用尽可能多的map任务。请参阅此博客文章以获取更多想法:http://www.cloudera.com/blog/2009/12/7-tips-for-improving-mapreduce-performance/

输出文件的大小:

简单地说,您可以指定多个reducer(每个reducer将生成一个输出文件)来实现这一点。如果您想按某些键(例如年-月)对结果进行分区,可以在map任务的输出键中包含该键,并将它们排序到同一个reducer中。然后您只需检查每个文件以查看它具有哪个年-月键。

压缩:

我建议您考虑对文件进行压缩。这样做将使输入文件“变大”,因为每个文件将包含更多数据供单个map任务操作。它还将减少集群中使用的磁盘量。如果有的话,它可能还会提高集群上mapreduce的性能,因为读取和移动文件时会发生更少的磁盘I/O和网络流量。

此外,压缩map任务的中间输出(从map任务输出到reducer之前)也会以类似的方式增加性能。这可以通过设置mapred.compress.map.output=true来完成。


3
Hadoop基于输入分割大小来划分工作。它通过将总数据大小除以分割大小来确定会发生多少个映射作业。一般认为,每台机器应该有10-100个映射;引自http://hadoop.apache.org/common/docs/r0.18.3/mapred_tutorial.html

映射数量通常由输入的总大小(即输入文件块的总数)驱动。映射的正确并行级别似乎是每个节点10-100个映射,虽然已经设置了300个映射以处理非常轻的CPU映射任务。任务设置需要一些时间,因此最好让映射至少执行一分钟。

对于某些输入格式,您可以设置分割大小,默认情况下大多数格式(包括TextInputFormat)每个块创建一个映射。因此,如果您有几个不同的文件,则会产生更多的不完整的64MB块,这是浪费映射的资源。
处理一个巨大的文件比处理多个文件要高效得多。当作业必须考虑多个文件时,其设置需要更长的时间。 Hadoop的核心实际上是围绕少量大文件而设计的。此外,HDFS设置为处理少量大文件,您拥有的文件越多,namenode将使用更多的RAM来跟踪它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接