从reducer输入聚合一个巨大的列表,而不会耗尽内存

时间:2017-05-12 18:46:57

标签: list hadoop memory collections mapreduce

在缩减阶段(降低百分比的67%),我的代码最终会在尝试完成数小时后卡住并失败。我发现问题是减速器正在接收大量的数据,它无法处理并最终耗尽内存,导致减速器卡住。

现在,我正试图找到解决这个问题的方法。目前,我正在根据每个密钥的reducer收到的值汇总一个列表。在reduce阶段结束时,我尝试写入列表中的键和所有值。所以我的问题是,如何在不耗尽内存的情况下获得与该键相关的键和值列表相同的功能?

public class XMLReducer extends Reducer<Text, Text, Text, TextArrayWritable> {
private final Logger logger = Logger.getLogger(XMLReducer.class);

@Override
public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException {
    //logger.info(key.toString());
    Set<String> filesFinal = new HashSet<>();
    int size = 0;
    for(Text value : values) {
        String[] files = value.toString().split(",\\s+");
        filesFinal.add(value.toString());
        //size++;
    }
    //logger.info(Integer.toString(size));
    String[] temp = new String[filesFinal.size()];
    temp = filesFinal.toArray(temp);
    Text[] tempText = new Text[filesFinal.size()];
    for(int i = 0; i < filesFinal.size(); i++) {
        tempText[i] = new Text(temp[i]);
    }               
}
}

和TextArrayWritable只是一种将数组写入文件

的方法

1 个答案:

答案 0 :(得分:0)

您可以尝试通过编写自定义分区程序来减少单个reducer读取的数据量。

HashPartitioner 是地图缩减作业使用的默认分区程序。虽然这可以保证您的均匀分布,但在某些情况下很可能会将许多键散列到单个reducer中。因此,与其他减速器相比,单个减速器将拥有大量数据。在你的情况下,我认为这是问题所在。

要解决此问题:

  1. 分析您的数据以及您正在进行分组的密钥。你
  2. 尝试根据您的自定义分区程序的按键分组功能。尝试限制每个分区的密钥数。
  3. 您会看到作业中减少任务数量的增加。如果问题与密钥分配不均匀有关,我提出的解决方案应解决您的问题。

    你也可以尝试增加减速机内存。