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

标签 list hadoop memory collections mapreduce

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

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

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 只是一种将数组写入文件的方法

最佳答案

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

哈希分区器 是 map reduce 作业使用的默认分区器。虽然这保证了您的均匀分布,但在某些情况下,很可能许多键被散列到单个 reducer。结果,与其他 reducer 相比,单个 reducer 将拥有大量数据。在你的情况下,我认为这是问题所在。

要解决此问题:

  • 分析您的数据和您正在分组的关键。你
  • 尝试根据您的组键为您的自定义分区器提供分区功能。尝试限制每个分区的键数。

  • 您会看到工作中 reduce task 的数量有所增加。如果问题与不均匀的 key 分配有关,我提出的解决方案应该可以解决您的问题。

    您也可以尝试增加 reducer 内存。

    关于list - 从 reducer 输入聚合一个巨大的列表而不会耗尽内存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43944628/

    相关文章:

    c - 为什么不能像单维那样访问多维数组

    c++ - 记住变量供下次使用

    python - 查找一个列表中的元素在另一个全包含列表中的存在数量

    mysql - 从 MySQL 选择表名作为文件发送到 HDFS

    python - 如何使用 pandas 现有列之一中的列表创建新列,并从另一列的列表中分配值?

    hadoop - hive 中的 Select 语句返回一些具有空值的列

    hadoop - 在Apache Pig中创建时间序列

    c - 是否存在内存泄漏?

    c++ - 清除 std::list 动态对象的最快方法是什么?

    android - 在 Kotlin 中更改可变列表中的值