如何将一个大序列文件拆分成多个序列文件?
How to split a big Sequence file into multiple sequence files?
我有一个包含大约 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)!
谁能建议 better/valid 方法?
也许我没有正确理解你的问题,但为什么不逐行阅读你的文件(=逐条输入?)并以此方式构建你的三个文件?
它会是这样的:
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 编码。
也许不是您正在寻找的确切答案,但可能值得尝试 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是不可拆分的。
我有一个包含大约 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)! 谁能建议 better/valid 方法?
也许我没有正确理解你的问题,但为什么不逐行阅读你的文件(=逐条输入?)并以此方式构建你的三个文件? 它会是这样的:
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 编码。
也许不是您正在寻找的确切答案,但可能值得尝试 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是不可拆分的。