我的数据集大小为3位GB,甚至是1或2位TB。因此,输入文件是一个文件列表,每个文件的大小为10GB。我的地图减少了hadoop中的作业处理所有这些文件,然后只提供一个输出文件(带有聚合信息)。
我的问题是:
从Apache调优hadoop / mapreduce框架的适当文件大小是多少?我听说更大的文件大小比小文件大。有什么想法吗?我唯一知道的是hadoop读取块,每个块默认为64MB。因此,如果文件大小是64MB的乘数,那将是很好的。
目前,我的应用程序只将输出文件写入一个文件。那么文件大小当然是3位千兆位。我想知道我如何有效地分区文件。当然我可以使用一些unix工具来完成这项工作。但是它是否更喜欢直接在hadoop中这样做?
谢谢你的意见!
P.S:
我没有压缩文件。输入文件的文件格式为text / csv。
如果你没有压缩文件,那么hadoop将处理你的大文件(例如10G),其中包含许多与文件块大小相关的映射器。
假设您的块大小为64M,那么您将有~160个映射器处理此10G文件(160 * 64~ = 10G)。根据映射器逻辑的CPU密集程度,这可能是一个可接受的块大小,但是如果发现映射器在子分钟内执行,那么您可能希望增加每个映射器完成的工作(通过增加块大小)到128,256,512m - 实际大小取决于您打算如何处理数据)。
较大的块大小将减少用于处理10G文件的映射器的数量。您当然可以增加TextInputFormat使用的最小分割大小,但是您很可能会遇到较低的数据位置,因为映射器可能正在处理2个或更多个块,这些块可能并非全部驻留在该节点上。
至于输出,这又取决于你的处理逻辑在做什么 - 你可以通过引入更多的reducer进行分区吗?这将创建更多的输出文件,但是您需要为这些文件分配逻辑(默认情况下,它们将由您的密钥进行散列分区)
输入文件的大小:
调整此方法的一种方法是查看地图任务完成的速度。每个地图任务将接收1个文件作为输入,如果它们在30-40秒内完成,则应考虑增加每个文件的大小,以便每个映射器有更多工作要做。这是因为在执行任何实际工作之前,map任务大约需要30秒才能初始化。
它还取决于您的群集一次可以运行多少个地图任务。您可以尝试调整文件和块大小,以便充分利用尽可能多的映射任务。有关更多创意,请参阅此博文: http://www.cloudera.com/blog/2009/12/7-tips-for-improving-mapreduce-performance/
输出文件的大小:
执行此操作的简单方法是指定多个reducer(每个reducer将生成一个输出文件)。如果要按某个键(例如,年 - 月)对结果进行分区,可以将其包含在地图任务的输出键中,并将它们分类到同一个reducer。然后,您只需检查每个文件以查看它具有的年月密钥。
压缩:
我建议您查看压缩文件。这样做会使输入文件“更大”,因为每个输入文件将包含更多数据,以便单个地图任务进行操作。它还会减少您在群集中使用的磁盘数量。如果有的话,它还可能会提高群集上mapreduce的性能,因为读取和移动文件会减少磁盘I / O和网络流量。
此外,压缩映射任务的中间输出(在映射任务输出到reducer之前从map任务输出)。它将以类似的方式提高性能。这是通过设置完成的 mapred.compress.map.output=true
。
Hadoop根据输入分割大小划分工作。它将您的总数据大小除以您的拆分大小,以及它确定将发生多少个地图作业的方式。普遍的共识是每台机器需要10到100张地图;从 http://hadoop.apache.org/common/docs/r0.18.3/mapred_tutorial.html
映射的数量通常由输入的总大小驱动,即输入文件的块总数。地图的正确并行度似乎是每个节点大约10-100个地图,尽管已经为非常cpu-light地图任务设置了300个地图。任务设置需要一段时间,因此最好是地图至少需要一分钟才能执行。
使用某些输入格式,您可以设置分割大小,默认情况下,大多数(包括TextInputFormat)每个块创建一个映射。因此,如果你有几个不同的文件,你最终会得到更多非完整的64mb块,这会浪费地图。
处理一个巨型文件比处理多个文件更有效。当必须考虑多个文件时,作业的设置需要更长的时间。 hadoop的核心实际上是围绕着少量大文件。此外,HDFS设置为处理少量大文件,你拥有的文件越多,namenode将使用的ram越多,以便跟踪它们。