Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/321.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.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
如何在Spark(使用Java)中将数据序列化为AVRO模式?_Java_Apache Spark_Hdfs_Avro_Spark Avro - Fatal编程技术网

如何在Spark(使用Java)中将数据序列化为AVRO模式?

如何在Spark(使用Java)中将数据序列化为AVRO模式?,java,apache-spark,hdfs,avro,spark-avro,Java,Apache Spark,Hdfs,Avro,Spark Avro,我已经定义了一个AVRO模式,并使用AVRO工具为这些模式生成了一些类。现在,我想将数据序列化到磁盘。我找到了一些关于scala的答案,但不适用于Java。类文章是使用avro工具生成的,并且是由我定义的模式生成的 下面是我如何尝试执行此操作的代码的简化版本: JavaPairRDD<String, String> filesRDD = context.wholeTextFiles(inputDataPath); JavaRDD<Article> processingFi

我已经定义了一个AVRO模式,并使用AVRO工具为这些模式生成了一些类。现在,我想将数据序列化到磁盘。我找到了一些关于scala的答案,但不适用于Java。类
文章
是使用avro工具生成的,并且是由我定义的模式生成的

下面是我如何尝试执行此操作的代码的简化版本:

JavaPairRDD<String, String> filesRDD = context.wholeTextFiles(inputDataPath);
JavaRDD<Article> processingFiles = filesRDD.map(fileNameContent -> {
    // The name of the file
    String fileName = fileNameContent._1();
    // The content of the file
    String fileContent = fileNameContent._2();

    // An object from my avro schema
    Article a = new Article(fileContent);

    Processing processing = new Processing();
    // .... some processing of the content here ... //

    processing.serializeArticleToDisk(avroFileName);

    return a;
});
其中,
Article
是我的avro模式

现在,映射程序向我抛出错误:

java.io.FileNotFoundException: hdfs:/...path.../avroFileName.avro (No such file or directory)   
at java.io.FileOutputStream.open0(Native Method)    
at java.io.FileOutputStream.open(FileOutputStream.java:270)     
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)   
at java.io.FileOutputStream.<init>(FileOutputStream.java:162)   
at org.apache.avro.file.SyncableFileOutputStream.<init>(SyncableFileOutputStream.java:60)   
at org.apache.avro.file.DataFileWriter.create(DataFileWriter.java:129)
at org.apache.avro.file.DataFileWriter.create(DataFileWriter.java:129)
at sentences.ProcessXML.serializeArticleToDisk(ProcessXML.java:207)     
. . . rest of the stacktrace ... 
java.io.FileNotFoundException:hdfs:/…path…/avroFileName.avro(没有这样的文件或目录)
位于java.io.FileOutputStream.open0(本机方法)
在java.io.FileOutputStream.open(FileOutputStream.java:270)
位于java.io.FileOutputStream。(FileOutputStream.java:213)
位于java.io.FileOutputStream。(FileOutputStream.java:162)
位于org.apache.avro.file.SyncableFileOutputStream。(SyncableFileOutputStream.java:60)
位于org.apache.avro.file.DataFileWriter.create(DataFileWriter.java:129)
位于org.apache.avro.file.DataFileWriter.create(DataFileWriter.java:129)
位于句子.ProcessXML.serializeArticleToDisk(ProcessXML.java:207)
. . . 剩余的堆栈跟踪。。。
尽管文件路径是正确的

之后我使用了
collect()
方法,因此
map
函数中的所有其他功能都可以正常工作(序列化部分除外)

我对Spark很陌生,所以我不确定这是否是一件小事。我怀疑我需要使用一些写入函数,而不是在映射器中进行写入(但不确定这是否正确)。有没有办法解决这个问题

编辑:

我显示的错误堆栈跟踪的最后一行实际上位于这一部分:

dataFileWriter.create(this.article.getSchema(),新文件(filename))


这是抛出实际错误的部分。我假设需要用其他东西替换
dataFileWriter
。有什么想法吗?

看来你用错了Spark

Map
是一个转换函数。仅仅调用
map
不会调用
RDD
的计算。您必须调用操作
forEach()
collect()

还要注意,提供给
map
的lambda将在驱动程序处序列化,并传输到集群中的一些
节点

已添加

尝试使用Spark SQL并以Avro格式保存Spark
DataFrame

// Load a text file and convert each line to a JavaBean.
JavaRDD<Person> people = sc.textFile("/examples/people.txt")
    .map(Person::parse);

// Apply a schema to an RDD
DataFrame peopleDF = sqlContext.createDataFrame(people, Person.class);
peopleDF.write()
    .format("com.databricks.spark.avro")
    .save("/output");
//加载一个文本文件,并将每一行转换为JavaBean。
JavaRDD people=sc.textFile(“/examples/people.txt”)
.map(Person::parse);
//将架构应用于RDD
DataFrame peopleDF=sqlContext.createDataFrame(people,Person.class);
peopleDF.write()
.format(“com.databricks.spark.avro”)
.save(“/output”);

此解决方案未使用数据帧,也未引发任何错误:

import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.io.NullWritable;
import org.apache.avro.mapred.AvroKey;
import org.apache.spark.api.java.JavaPairRDD;
import scala.Tuple2;

   .  .  .  .  .

// Serializing to AVRO
JavaPairRDD<AvroKey<Article>, NullWritable> javaPairRDD = processingFiles.mapToPair(r -> {    
    return new Tuple2<AvroKey<Article>, NullWritable>(new AvroKey<Article>(r), NullWritable.get());
});
Job job = AvroUtils.getJobOutputKeyAvroSchema(Article.getClassSchema());
javaPairRDD.saveAsNewAPIHadoopFile(outputDataPath, AvroKey.class, NullWritable.class, AvroKeyOutputFormat.class, 
        job.getConfiguration());

Spark+Avro的类似情况可以在这里找到->。

你们在说什么--
map
绝对会调用
RDD
的计算
map
返回一个新的
RDD
,其中所有元素都是根据
map
函数重新计算的。@Denis Kokorin:我在之后使用
collect()
,所以
map
中的所有元素都已经工作了,这很好。除了序列化之外的任何东西都可以在
map
函数中工作。也许他的意思是你应该在
map
之后加上
foreach
,然后在那里写作?如果这个答案有示例代码可能会有帮助。很抱歉之前没有提到。但您的错误指向
hdfs:/…path…/avroFileName.avro
。默认情况下,HDFS协议不是由Java解析的。尝试使用Hadoop的文件系统打开
OutputStream
。另外,您明确不应该使用
map()
将某些内容保存到HDFS。使用
foreach()
store()
。我已经编辑了我的原始帖子。对不起,你这么误会了。我匆忙地写下了这个答案。也许可以看看这里的讨论和答案:我已经看到了这个答案,我对Java等价物更感兴趣。谢谢你的评论!
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.io.NullWritable;
import org.apache.avro.mapred.AvroKey;
import org.apache.spark.api.java.JavaPairRDD;
import scala.Tuple2;

   .  .  .  .  .

// Serializing to AVRO
JavaPairRDD<AvroKey<Article>, NullWritable> javaPairRDD = processingFiles.mapToPair(r -> {    
    return new Tuple2<AvroKey<Article>, NullWritable>(new AvroKey<Article>(r), NullWritable.get());
});
Job job = AvroUtils.getJobOutputKeyAvroSchema(Article.getClassSchema());
javaPairRDD.saveAsNewAPIHadoopFile(outputDataPath, AvroKey.class, NullWritable.class, AvroKeyOutputFormat.class, 
        job.getConfiguration());
public static Job getJobOutputKeyAvroSchema(Schema avroSchema) {
    Job job;

    try {
        job = new Job();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }

    AvroJob.setOutputKeySchema(job, avroSchema);
    return job;
}