Scrunch与Crunch中的可写类型族分辨率

时间:2015-12-09 18:25:46

标签: scala apache-crunch

我有一个Scrunch Spark管道,当我尝试使用以下方法将其输出保存为Avro格式时:

data.write(to.avroFile(path))

我得到以下例外:

java.lang.ClassCastException: org.apache.crunch.types.writable.WritableType cannot be cast to org.apache.crunch.types.avro.AvroType
at org.apache.crunch.io.avro.AvroFileTarget.configureForMapReduce(AvroFileTarget.java:77) ~[crunch-core-0.14.0-SNAPSHOT.jar:0.14.0-SNAPSHOT]
at org.apache.crunch.impl.spark.SparkRuntime.monitorLoop(SparkRuntime.java:327) [crunch-spark-0.14.0-SNAPSHOT.jar:0.14.0-SNAPSHOT]
at org.apache.crunch.impl.spark.SparkRuntime.access$000(SparkRuntime.java:80) [crunch-spark-0.14.0-SNAPSHOT.jar:0.14.0-SNAPSHOT]
at org.apache.crunch.impl.spark.SparkRuntime$2.run(SparkRuntime.java:139) [crunch-spark-0.14.0-SNAPSHOT.jar:0.14.0-SNAPSHOT]

虽然这样可以正常工作:

data.write(to.textFile(path))

(在两种情况下data都是PCollection相同实例和path字符串

我理解为什么会发生错误,我尝试编写的PCollection属于Writable类型系列而不是Avro类型。我不清楚的是如何在Scrunch中决定我的PCollection属于一个而不是另一个。

然而,这种机制在Crunch中似乎更为明显。根据{{​​3}}:

  

Crunch支持两种不同的类型系列,每种类型都实现了PTypeFamily接口:一个用于Hadoop的可写接口,另一个用于基于Apache Avro。还有一些类包含每个PTypeFamily的静态工厂方法,以便于导入和使用:一个用于Writable,一个用于Avros。

然后:

  

对于大多数管道,您将专门使用一个类型系列,因此您可以通过将Writables或Avros类中的所有方法导入到类中来减少类中的某些样板

     

import static org.apache.crunch.types.avro.Avros。*;

事实上,在正式回购中为Crunch提供的示例中,可以看出这是如何明确的。请参阅official Crunch documentation示例中的以下代码段:

PCollection<String> lines = pipeline.readTextFile(args[0]);

PCollection<String> words = lines.parallelDo(new DoFn<String, String>() {
  public void process(String line, Emitter<String> emitter) {
    for (String word : line.split("\\s+")) {
      emitter.emit(word);
    }
  }
}, Writables.strings()); // Indicates the serialization format

PTable<String, Long> counts = words.count();

虽然等效的WordCount是这样的:

 def countWords(file: String) = {
read(from.textFile(file))
  .flatMap(_.split("\\W+").filter(!_.isEmpty()))
  .count

}

没有明确的,或者据我所知,提供了对WritableFamily的隐式引用。

那么Scrunch如何决定使用哪种Writable族类型?它是基于原始输入源的默认值吗? (例如,如果从文本文件中读取,它是可写的,如果来自Avro然后是Avro)如果是这种情况,那么我怎么能改变从一个源读取的类型并写入目标taht属于不同的家庭类型在Scrunch?

0 个答案:

没有答案