我有一个包含大约6000万条目(大约4.5GB)的大型序列文件。 我想分开它。例如,我想将它分成三部分,每部分有2000万个条目。到目前为止我的代码是这样的:
//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 :(得分: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不可拆分。
答案 1 :(得分: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++;
}
在这种情况下,每三行一行进入第一个文件,第二个和第三个文件。
另一种解决方案是使用Files.readAllBytes(Paths.get(inputFileName))
进行二进制读取(如果文件不是文本文件)并使用Files.write(Paths.get(output1), byteToWrite)
写入输出文件。
但是,我没有回答为什么输出在你的方式上占据了更多的位置。也许编码是有罪的?我认为java默认编码为UTF-8,输入文件可能用ASCII编码。