如何将一个大的序列文件拆分成多个序列文件?

时间:2017-05-03 12:55:55

标签: java apache-spark rdd sequencefile bigdata

我有一个包含大约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)! 任何人都可以提出更好/更有效的方法吗?

2 个答案:

答案 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编码。