我正在以一种不同的方式使用 hadoop。就我而言,输入大小非常小。但是,计算时间更长。我有一些复杂的算法,我将在每一行输入上运行。因此,即使输入大小小于 5mb,总计算时间也超过 10 小时。所以我在这里使用hadoop。我正在使用 NLineInputFormat 按行数而不是块大小来拆分文件。在我最初的测试中,我有大约 1500 行(拆分为 200 行),与在一台机器上串行运行相比,我看到在四节点集群中只提高了 1.5 倍。我正在使用虚拟机。这可能是问题还是对于较小尺寸的输入,hadoop 不会有太多好处?任何见解都会非常有帮助。
2 回答
对我来说,你的工作量类似于 SETI@Home 的工作量——负载量小,但需要数小时的工作时间。
Hadoop(或更具体地说是 HDFS)不是为大量小文件设计的。但我怀疑这是 MapReduce 的问题 - 您正在使用的处理框架。
如果您想将您的工作负载保持在一起:1)如果文件小于块大小,则将它们拆分为单独的文件(一个工作负载,一个文件),那么它将转到一个映射器。典型的块大小为 64MB 或 128MB
2) 为 FileInputFormat 创建一个包装器,并将 'isSplitable()' 方法重写为 false。这将确保将整个文件内容馈送到一个映射器,而不是 hadoop 试图逐行拆分它
参考:http ://hadoopilluminated.com/hadoop_book/HDFS_Intro.html
Hadoop 并不擅长处理大量的小文件,因此,通常希望将大量较小的输入文件组合成较少数量的较大文件,以减少映射器的数量。
由于 Hadoop MapReduce 过程的输入由InputFormat
. FileInputFormat
是处理 HDFS 中文件的默认实现。使用FileInputFormat
,每个文件都被拆分为一个或多个InputSplits
通常以 为上限的文件block size
。这意味着输入拆分的数量低于输入文件的数量。当 MapReduce 进程处理大量小文件时,这不是一个理想的环境,因为协调分布式进程的开销远大于小文件数量相对较多时的开销。
驱动吐出尺寸的基本参数是mapred.max.split.size
。
使用CombineFileInputFormat
和这个参数我们可以控制映射器的数量。
在这里查看我的另一个答案的实现。