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

nqwrtyyt  于 2021-06-02  发布在  Hadoop
关注(0)|答案(1)|浏览(325)

在reduce阶段(reduce百分比的67%),经过数小时的尝试,我的代码最终被卡住并失败。我发现问题是reducer接收到大量无法处理的数据,最终耗尽内存,导致reducer被卡住。
现在,我在想办法解决这个问题。目前,我正在从每个键的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只是一种将数组写入文件的方法

aelbi1ox

aelbi1ox1#

您可以尝试通过编写自定义分区器来减少单个缩减器读取的数据量。
hashpartitioner是map reduce作业使用的默认分区器。虽然这可以保证均匀分布,但在某些情况下,很可能会将许多密钥散列到单个缩减器中。因此,与其他减速器相比,单个减速器将拥有大量数据。就你而言,我认为这就是问题所在。
要解决此问题:
分组分析您的数据和正在执行的关键点。你呢
尝试为您的自定义分区器提供一个基于groupby键的分区函数。尝试限制每个分区的密钥数。
你会看到你工作中减少任务的数量在增加。如果问题与密钥分布不均匀有关,那么我提出的解决方案应该可以解决您的问题。
你也可以尝试增加内存。

相关问题