生成数千个贴图的Pig脚本



由于某种原因,该脚本在一个小输入上生成了60000个地图作业:

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个映射作业。这会导致许多其他问题——有时应用程序管理器内存不足,有时在混洗阶段挂起,以及其他各种内存不足错误。

它似乎不应该为这么小的输入创建这么多拆分。我尝试过增加最大.CombinedSplitSize、mapred.min.split.size和dfs.block.size,但没有影响映射的数量(这是有道理的,因为我正在处理的是少量的小文件)。我可能会继续增加投入工作的资源,但在某种程度上,这些价值观超出了我的控制。

可能值得注意的是,这个脚本在本地运行良好——只有当它在实际的hadoop集群上运行并从HDFS中实际读取时,才会出现这个问题。

其他人有没有遇到过类似的问题?如果有,你做了什么改变来解决这个问题?

发现问题出在我的CustomLoader中(这是我没有预料到的)。加载程序可以定义自己的分割,并创建了大量的分割,这转化为大量的映射。这个自定义加载程序明确地没有将拆分分组在一起(尽管我认为它们在默认情况下可能不会分组),所以即使许多拆分是空的或很小,它们也各自产生了自己的映射作业。由于自定义加载程序是在我的所有配置更改之后加载的,它覆盖了允许我分组拆分的配置。

对于那些感兴趣的人,我在子类InputFormat类的List<InputSplit> getSplits(final JobContext context)方法中发现了拆分问题,该方法是从LoadFunc的自定义子类中的InputFormat getInputFormat()返回的。

最新更新