2017-05-03 1 views
1

약 6 천만 개의 항목 (거의 4.5GB)이 포함 된 큰 시퀀스 파일이 있습니다. 분할하고 싶습니다. 예를 들어, 나는 그것을 3 개의 부분으로 나누고 싶다. 각각은 2 천만 개의 항목을 갖고있다. 지금까지 내 코드는 다음과 같습니다.큰 시퀀스 파일을 여러 시퀀스 파일로 분할하는 방법은 무엇입니까?

//Read from sequence file 
    JavaPairRDD<IntWritable,VectorWritable> seqVectors = sc.sequenceFile(inputPath, IntWritable.class, VectorWritable.class); 
    JavaPairRDD<IntWritable,VectorWritable> part=seqVectors.coalesce(3); 
    part.saveAsHadoopFile(outputPath+File.separator+"output", IntWritable.class, VectorWritable.class, SequenceFileOutputFormat.class); 

불행하게도 생성 된 시퀀스 파일은 각각 약 4GB (총 12GB)입니다. 누구나 더 나은/유효한 접근 방식을 제안 할 수 있습니까?

+0

당신이 한 일은 IMHO로가는 길입니다. 파일을 동일한 크기로 만들려면 –

+0

을 병합하지 말고 다시 파티션을 사용하지만 파티션을 다시 지정하면 오류가 발생합니다. -> 17/05/03 23:10:46 오류 executor.Executor : 0.0 단계의 작업 1.0 예외 (TID 1) com.esotericsoftware.kryo.KryoException : java.util.ConcurrentModificationException 직렬화 추적 : 클래스 (sun.misc.Launcher $ AppClassLoader) classLoader가 (org.apache.hadoop.mapred.JobConf) conf의 (org.apache.mahout .mot.VectorWritable) ---- 세부 정보 추적 ---> https://pastebin.com/eDWvV6Fx @TalJoffe – user3086871

+0

문제가 shuffling에 있다고 생각합니다. 왜냐하면 내가 coalesce (3, true) 같은 문제를 사용하기 때문에 던졌습니다! – user3086871

답변

1

아마 정확한 대답은 아니지만, the second method for sequenceFile 읽기를 시도해 볼 가치가 있습니다. minPartitions 인수를 취하는 것이 좋습니다. 사용중인 coalesce은 파티션 만 줄일 수 있습니다.

코드는 다음과 같아야합니다

//Read from sequence file 
JavaPairRDD<IntWritable,VectorWritable> seqVectors = sc.sequenceFile(inputPath, IntWritable.class, VectorWritable.class, 3); 
seqVectors.saveAsHadoopFile(outputPath+File.separator+"output", IntWritable.class, VectorWritable.class, SequenceFileOutputFormat.class); 

문제가 발생할 수있는 또 다른 것은 어떤 SequenceFiles는 분열성하지 않는 것입니다.

0

어쩌면 내가 옳은 질문을 이해하지 못 하겠지만 왜 파일을 한 줄씩 (= 항목별로 입력합니까?) 읽어 보지 않고이 방법으로 세 가지 파일을 빌드해야합니까? 그것은이 같은 것입니다 :

int i = 0; 
List<PrintWriter> files = new ArrayList<PrintWriter>(); 
files.add(new PrintWriter("the-file-name1.txt", "UTF-8")); 
files.add(new PrintWriter("the-file-name2.txt", "UTF-8")); 
files.add(new PrintWriter("the-file-name3.txt", "UTF-8")); 
for String line in Files.readAllLines(Paths.get(fileName)){ 
    files.get(i % 3).writeln(line); 
    i++; 
} 

이 경우, 한 줄 매 3 개 라인은 프리스트, 두 번째와 세 번째 파일로 이동합니다.

다른 해결책은 파일이 텍스트 파일이 아닌 경우 Files.readAllBytes(Paths.get(inputFileName))을 사용하고 출력 파일에 Files.write(Paths.get(output1), byteToWrite)을 쓰는 것입니다.

그러나 출력이 왜 그렇게하고 있는지에 대한 대답은 없습니다. 인코딩이 유죄일까요? 자바는 기본적으로 UTF-8로 인코딩되고 입력 파일은 ASCII로 인코딩 될 수 있다고 생각합니다.

+0

텍스트 파일이 아니며 시퀀스 파일입니다. . 텍스트 파일의 경우이 작업을 쉽게 수행 할 수 있으며 시퀀스 파일에 대해 라인별로 접근 방식을 취할 수도 있지만 스파크 rdd 관점에서 가장 좋은 방법은 무엇인지 찾고 있습니다 – user3086871

관련 문제