[HADOOP] 큰 (> 1GB) BytesWritable 값 크기로 SequenceFile을 만들 때 NegativeArraySizeException
HADOOP큰 (> 1GB) BytesWritable 값 크기로 SequenceFile을 만들 때 NegativeArraySizeException
나는 큰 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와 같은 다른 접근법을 시도했지만 힙 크기 또는 OOME이 있습니다.
해결법
-
==============================
1.대신 ArrayPrimitiveWritable을 사용하십시오.
대신 ArrayPrimitiveWritable을 사용하십시오.
BytesWritable에서 새로운 용량을 설정하면 int overflow가 발생합니다.
public void setSize(int size) { if (size > getCapacity()) { setCapacity(size * 3 / 2); } this.size = size; }
700 Mb * 3> 2Gb = int 오버 플로우!
결과적으로 700MB 이상의 직렬화를 BytesWritable에 직렬화 해제 할 수는 없지만 쓰기 및 직렬화 할 수는 있습니다.
-
==============================
2.BytesWritable을 사용하려는 경우 옵션이 용량을 충분히 높게 설정하므로 700MB뿐만 아니라 2GB를 사용합니다.
BytesWritable을 사용하려는 경우 옵션이 용량을 충분히 높게 설정하므로 700MB뿐만 아니라 2GB를 사용합니다.
randomValue.setCapacity(numBytesToWrite); randomValue.setSize(numBytesToWrite); // will not resize now
이 버그는 최근 Hadoop에서 수정되었으므로 최신 버전에서는 해당 기능 없이도 작동합니다.
public void setSize(int size) { if (size > getCapacity()) { // Avoid overflowing the int too early by casting to a long. long newSize = Math.min(Integer.MAX_VALUE, (3L * size) / 2L); setCapacity((int) newSize); } this.size = size; }
from https://stackoverflow.com/questions/24127304/negativearraysizeexception-when-creating-a-sequencefile-with-large-1gb-bytesw by cc-by-sa and MIT license
'HADOOP' 카테고리의 다른 글
[HADOOP] Hadoop을 사용하여 데이터 노드에서 임시 파일을 쓰는 문제 (0) | 2019.08.10 |
---|---|
[HADOOP] oozie에서 여러 jar 파일을 지정하는 방법 (0) | 2019.08.10 |
[HADOOP] emr에서 hadoop 클러스터를 다시 시작하는 방법 (0) | 2019.08.10 |
[HADOOP] CSV 파일의 문자열에 큰 따옴표와 함께 하이브 테이블에 삽입 된 값 (0) | 2019.08.10 |
[HADOOP] Hive 오류 : 기본 오류 : org.apache.hadoop.hive.ql.exec.UDFArgumentTypeException : 하나 이상의 인수가 필요합니다 (0) | 2019.08.10 |