我编写了一个自定义Map Reduce代码来模拟FlatMap行为,即mapper的输入是一个S3位置,其中包含{Key,collection}的元组。映射器仅迭代数据并返回集合。 映射器的输入是S3中的27个文件,每个文件大小为238 MB。当map / reduce代码运行时,决定的分割是57.作业的reducer数量是0。
映射器代码:
@Override
protected void map(final LongWritable key, @Nonnull final Text value, @Nonnull final Context context)
throws IOException, InterruptedException {
Objects.requireNonNull(value);
Objects.requireNonNull(context);
T input;
try {
input = mapper.readValue(value.toString(), componentFunction.getInputClass());
} catch (Exception e ) {
throw new CafeMapReduceException("Failed to deserialize input: " + value.toString(), e);
}
PartitionerFlatmapComponentOutput output = new PartitionerFlatmapComponentOutput().setNotifications(input.getNotificationTuple().getValue());
writeToContext(context, output);
}
protected void writeToContext(@Nonnull final Context context, @Nonnull final U output)
throws IOException, InterruptedException {
if (output instanceof Collection) {
for (Object element : (Collection) output) {
context.write(NullWritable.get(), new Text(mapper.writeValueAsString(element)));
}
} else {
throw new CafeMapReduceException("Invalid output for flatMap. Output type: " + output.getClass());
}
}
我尝试使用以下配置运行此代码: mapreduce.map.java.opts = -Xmx4096m 但是,它在Java Heap Space问题上失败了。我甚至尝试使用多个GC算法,如-XX:+ UseParallelGC,concurrentGC但它仍然失败并出现相同的错误。
当我们向mapper提供10 GB的堆空间时,Mappers成功完成。
我无法弄清楚为什么映射器需要10 GB的内存。我正在使用Hadoop 2.7.3。我们应以何种方式帮助您解决此问题,这将有所帮助。
...添加更多详细信息......
发送到mapper的每个250 MB只有1行,即Tuple {Key,Collection}的JSON表示。我得到了堆转储并运行了分析器,它显示了以下内容:
线程java.lang.Thread @ 0x6c018b708 main保留局部变量,总大小为3,030,076,656(98.29%)字节。
我知道为什么本地变量会保留这么多内存。