Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何将一个大序列文件拆分为多个序列文件?_Java_Apache Spark_Rdd_Sequencefile_Bigdata - Fatal编程技术网

Java 如何将一个大序列文件拆分为多个序列文件?

Java 如何将一个大序列文件拆分为多个序列文件?,java,apache-spark,rdd,sequencefile,bigdata,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); JavaPairRD

我有一个大的序列文件,大约有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);
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++;
}
//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);
//从序列文件读取
javapairdd seqVectors=sc.sequenceFile(inputPath、IntWritable.class、VectorWritable.class);
javapairdd部分=seqVectors.coalesce(3);
part.saveAshadopFile(outputPath+File.separator+“output”、IntWritable.class、VectorWritable.class、SequenceFileOutputFormat.class);
但不幸的是,生成的每个序列文件也大约有4GB(总共12GB)!
有谁能提出一个更好/有效的方法吗?

也许我没有正确理解你的问题,但为什么不逐行阅读你的文件(=逐条阅读?),并以这种方式构建你的三个文件呢? 应该是这样的:

//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);
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++;
}
//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);
inti=0;
列表文件=新的ArrayList();
添加(新的PrintWriter(“the-file-name1.txt”、“UTF-8”);
添加(新的PrintWriter(“the-file-name2.txt”、“UTF-8”);
添加(新的PrintWriter(“the-file-name3.txt”、“UTF-8”);
用于Files.readAllLines(path.get(fileName))中的字符串行{
文件.get(i%3).writeln(行);
i++;
}
在本例中,每三行有一行进入第一个、第二个和第三个文件

另一种解决方案是,如果文件不是文本文件,则使用
Files.readAllBytes(path.get(inputFileName))
进行二进制读取,并使用
Files.write(path.get(output1),byteToWrite)写入输出文件中


然而,我没有一个答案来解释为什么输出在您的工作方式中占据如此多的位置。也许编码是有罪的?我认为java默认使用UTF-8编码,而您的输入文件可能使用ASCII编码。

也许不是您要寻找的确切答案,但可能值得一读,这个答案需要一个参数。请记住,您正在使用的
coalesce
,只能减少分区

然后,您的代码应该如下所示:

//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);
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++;
}
//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);
//从序列文件读取
javapairdd seqVectors=sc.sequenceFile(inputPath,IntWritable.class,VectorWritable.class,3);
seqVectors.saveAshadopFile(outputPath+File.separator+“output”、intwriteable.class、vectorwriteable.class、SequenceFileOutputFormat.class);

另一个可能导致问题的原因是某些SequenceFile不可拆分

它不是文本文件,而是序列文件。在文本文件的情况下,我可以很容易地做到这一点,我也可以对序列文件采取逐行的方法,我认为,但我正在寻找从spark rdd的角度来看最好的方法。你所做的就是这样做。如果希望文件大小相同,请使用重新分区而不是合并,但重新分区会给出错误-->17/05/03 23:10:46错误执行器。执行器:阶段0.0(TID 1)中任务1.0中的异常com.esotericsoftware.kryo.KryoException:java.util.ConcurrentModificationException序列化跟踪:类(sun.misc.Launcher$AppClassLoader)classLoader(org.apache.hadoop.mapred.JobConf)conf(org.apache.mahout.math.VectorWritable)--细节跟踪---->@taljoffee我认为问题在于洗牌,因为如果我使用coalesce(3,true),同样的问题会被抛出!如果RDD中的对象不可序列化,则有可能。。。您可以尝试将它们序列化,或者另一个选项是将RDD转换为Dataframe,然后进行重新分区