我尝试了不同的方法来创建一个大型hadoop sequencefile,只需一个短(<100bytes)键,但一个大(>1gb)值(byteswriteable)。
以下示例适用于开箱即用:
https://svn.apache.org/repos/asf/hadoop/common/trunk/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-jobclient/src/test/java/org/apache/hadoop/mapred/bigmapoutput.java
它写入多个随机长度的键和值,总大小大于3gb。
然而,这不是我想要做的。所以我使用hadoop 2.2.0 api将其修改为:
Path file = new Path("/input");
SequenceFile.Writer writer = SequenceFile.createWriter(conf,
SequenceFile.Writer.file(file),
SequenceFile.Writer.compression(CompressionType.NONE),
SequenceFile.Writer.keyClass(BytesWritable.class),
SequenceFile.Writer.valueClass(BytesWritable.class));
int numBytesToWrite = fileSizeInMB * 1024 * 1024;
BytesWritable randomKey = new BytesWritable();
BytesWritable randomValue = new BytesWritable();
randomKey.setSize(1);
randomValue.setSize(numBytesToWrite);
randomizeBytes(randomValue.getBytes(), 0, randomValue.getLength());
writer.append(randomKey, randomValue);
writer.close();
当filesizeinmb>700mb时,会出现如下错误:
java.lang.NegativeArraySizeException
at org.apache.hadoop.io.BytesWritable.setCapacity(BytesWritable.java:144)
at org.apache.hadoop.io.BytesWritable.setSize(BytesWritable.java:123)
...
我看到这个错误正在讨论中,但没有看到任何解决办法。请注意,int(2^32)可以大到2gb,它不应该在700mb时失败。
如果您有其他选择来创建如此大的值sequencefile,请告知。我尝试了其他方法,比如ioutils.read from inputstream into a byte[],我得到了堆大小或oome。
2条答案
按热度按时间nkkqxpd91#
只需使用ArrayPrimitiveWriteable即可。
在byteswritable中设置新容量会导致int溢出:
700 mb*3>2gb=int溢出!
因此,您不能反序列化(但可以写入和序列化)超过700 mb的字节可写。
zsohkypk2#
如果你想用
BytesWritable
,之前有一个选项将容量设置得足够高,因此您可以使用2gb,而不仅仅是700mb:这个bug最近在hadoop中得到了修复,因此在较新的版本中,即使没有这个bug,它也可以工作: