出于某种原因,此脚本在一个小的输入上生成60000个Map作业:
A1 = LOAD '$directory1' USING CustomLoader AS key:chararray;
A = FOREACH A1 GENERATE CustomParser(key) AS key:chararray;
B = LOAD '$filename1' USING PigStorage AS (key:chararray);
result = JOIN A BY key, B BY key USING 'replicated';
directory1有几个文件组成了大约10000行的数据,filename1也有大约10000行的数据,这些数据基本上都是短字符串。目录和文件都存储在hdfs中。两者都不是特别大,在10-100千字节的范围内。但是,当我在hadoop中运行脚本时,它会生成60000个Map作业。这会导致许多其他问题—有时应用程序管理器内存不足,有时在无序播放阶段挂起,以及各种各样的内存不足错误。
它似乎不应该为这么小的输入创建这么多拆分。我尝试过增加max.combinedsplitsize、mapred.min.split.size和dfs.block.size,但没有影响Map的数量(这是有意义的,因为我处理的是少量小文件)。我可能会不断增加投入到工作中的资源,但在某种程度上,这些值超出了我的控制范围。
可能值得注意的是,这个脚本在本地工作得很好——只有在实际的hadoop集群上运行并实际从hdfs读取时,才会出现这个问题。
有没有其他人遇到过类似的问题,如果有,您做了哪些更改来解决问题?
1条答案
按热度按时间w41d8nur1#
结果发现问题出在我的customloader中(这是我没想到的)。加载程序可以定义自己的拆分,并且创建了大量的拆分,这将转化为大量的Map。这个自定义加载程序没有显式地将拆分组合在一起(尽管我认为它们在默认情况下可能不会组合在一起),因此即使许多拆分是空的或很小的,它们也各自生成了自己的Map作业。由于自定义加载程序是在我所有的配置更改之后加载的,所以它会覆盖允许我分组拆分的配置。
对于那些感兴趣的人,我在子类inputformat类的
List<InputSplit> getSplits(final JobContext context)
方法,从InputFormat getInputFormat()
在loadfunc的自定义子类中。