在减少阶段(减少百分比的 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/