我最近正在学习Phoenix CSV批量加载,我发现org.apache.phoenix.mapreduce.CsvToKeyValueReducer
的源代码会在一行中的列很大时导致OOM(java堆内存不足)(在我的情况下,一列中有44列)行和一行的平均大小是4KB)。
此外,此类与hbase批量减载类 - KeyValueSortReducer
类似。这意味着在我的案例中使用KeyValueSortReducer
时可能会发生OOM。
所以,我有一个问题KeyValueSortReducer
- 为什么需要首先对treeset中的所有kv进行排序然后将它们全部写入上下文?如果我删除了树集排序代码并将所有kvs直接转换为上下文,结果会有所不同或是错误的吗?
我期待着你的回复。祝你好运!
这是KeyValueSortReducer的源代码:
public class KeyValueSortReducer extends Reducer<ImmutableBytesWritable, KeyValue, ImmutableBytesWritable, KeyValue> {
protected void reduce(ImmutableBytesWritable row, java.lang.Iterable<KeyValue> kvs,
org.apache.hadoop.mapreduce.Reducer<ImmutableBytesWritable, KeyValue, ImmutableBytesWritable, KeyValue>.Context context)
throws java.io.IOException, InterruptedException {
TreeSet<KeyValue> map = new TreeSet<KeyValue>(KeyValue.COMPARATOR);
for (KeyValue kv: kvs) {
try {
map.add(kv.clone());
} catch (CloneNotSupportedException e) {
throw new java.io.IOException(e);
}
}
context.setStatus("Read " + map.getClass());
int index = 0;
for (KeyValue kv: map) {
context.write(row, kv);
if (++index % 100 == 0) context.setStatus("Wrote " + index);
}
}
}
答案 0 :(得分:2)
请查看this case study。有一些要求,您需要将键值对订购到HFile的同一行。
答案 1 :(得分:1)
1.主要问题:为什么hbase KeyValueSortReducer需要对所有KeyValue进行排序?
感谢RamPrasad G的回复,我们可以查看案例研究:http://www.deerwalk.com/blog/bulk-importing-data/
本案例研究将告诉我们更多关于hbase批量导入和reducer类 - KeyValueSortReducer的信息。 在KeyValueSortReducer reduce方法中排序所有KeyValue的原因是HFile需要这种排序。你可以专注于这一部分:
减少时经常出现的问题是词汇排序。当从reducer输出的keyvalue列表没有排序时,会发生这种情况。一个示例是单个行的限定符名称不以词汇递增顺序写入。另一种情况是,在同一个reduce方法中写入多行时,行id不以词汇递增的顺序写入。这是因为reducer输出永远不会被排序。所有排序都发生在mapper输出的keyvalue上,然后才进入reduce方法。因此,它尝试以递增方式添加从reduce方法输出的keyvalue,假设它是预先排序的。因此,在将keyvalue写入上下文之前,必须将它们添加到排序列表中,如TreeSet或HashSet,并使用KeyValue.COMPARATOR作为比较器,然后按排序列表指定的顺序写入它们。
因此,当您的列非常大时,它将使用大量内存进行排序。 作为KeyValueSortReducer的源代码记忆:
/**
* Emits sorted KeyValues.
* Reads in all KeyValues from passed Iterator, sorts them, then emits
* KeyValues in sorted order. If lots of columns per row, it will use lots of
* memory sorting.
* @see HFileOutputFormat
*/
2.引用的问题:为什么Phoenix CSV BulkLoad reducer casue OOM?
Phoenix CSV BulkLoad reducer casue OOM的原因是PHOENIX-2649。
由于比较器内部CsvTableRowKeyPair
错误比较两个CsvTableRowKeyPair并使所有行在一个reduce调用中通过一个reducer,
在我的情况下,它会迅速导致OOM。
幸运的是,凤凰队已经修复了4.7版本的这个问题。如果您的凤凰版本低于4.7,请注意并尝试更新您的版本, 或者你可以修补你的版本。
我希望这个答案可以帮到你!