繁体   English   中英

java.lang.ClassCastException:org.apache.avro.generic.GenericData $ Record无法强制转换为packagename.MyRecord

[英]java.lang.ClassCastException: org.apache.avro.generic.GenericData$Record cannot be cast to packagename.MyRecord

我试图使用Spark 1.5.1(使用Scala 2.10.2)从HDFS读取一些.avro文件(使用spark-avro 1.7.7),以便对它们进行一些计算。

现在,我已经搜查彻底网页找到一个解决方案(也是迄今为止最好的链接的假设开始的这一个是建议使用一个GenericRecord,而这一个报告了同样的问题,而这一次是行不通的对我来说,因为它提供的代码几乎与我使用的相同),我在这里问,因为可能有人有相同的代码。 这是代码:

import org.apache.avro.mapred.{AvroInputFormat, AvroWrapper} 
import org.apache.hadoop.io.NullWritable 
import org.apache.spark.{SparkConf, SparkContext}

object SparkPOC {

  def main(args: Array[String]): Unit ={

    val conf = new SparkConf()
      .setAppName("SparkPOC")
      .set("spark.master", "local[4]")
    val sc = new SparkContext(conf)
    val path = args(0)
    val profiles = sc.hadoopFile(
      path,
      classOf[AvroInputFormat[MyRecord]],
      classOf[AvroWrapper[MyRecord]],
      classOf[NullWritable]
    )

    val timeStamps = profiles.map{ p => p._1.datum.getTimeStamp().toString}
    timeStamps.foreach(print)

}

我收到以下消息:

java.lang.ClassCastException: org.apache.avro.generic.GenericData$Record cannot be cast to packagename.MyRecord
    at packagename.SparkPOC$$anonfun$1.apply(SparkPOC.scala:24)
    at packagename.SparkPOC$$anonfun$1.apply(SparkPOC.scala:24)
    at scala.collection.Iterator$$anon$11.next(Iterator.scala:328)
    at scala.collection.Iterator$class.foreach(Iterator.scala:727)
    at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
    at org.apache.spark.rdd.RDD$$anonfun$foreach$1$$anonfun$apply$28.apply(RDD.scala:890)
    at org.apache.spark.rdd.RDD$$anonfun$foreach$1$$anonfun$apply$28.apply(RDD.scala:890)
    at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1848)
    at org.apache.spark.SparkContext$$anonfun$runJob$5.apply(SparkContext.scala:1848)
    at org.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
    at org.apache.spark.scheduler.Task.run(Task.scala:88)
    at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:214)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    at java.lang.Thread.run(Thread.java:744)

有人有线索吗? 我也在考虑使用spark-avro的可能性,但它们不支持同时从多个文件中读取(而.hadoopFile支持通配符)。 否则,似乎我必须使用GenericRecord并使用.get方法,失去编码模式(MyRecord)的优势。

提前致谢。

我通常以GenericRecord的形式阅读它并根据需要明确地转换,即

val conf = sc.hadoopConfiguration
sc.newAPIHadoopFile(path, classOf[AvroKeyInputFormat[GenericRecord]], classOf[AvroKey[GenericRecord]], classOf[NullWritable], conf).map(_._1.datum().asInstanceOf[MyRecord])

我设置了KryoSerializer和spark.kryo.registrator类之后,问题就出现了,如下所示:

val config = new SparkConf()
  .setAppName(appName)
  .set("spark.master", master)
  .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
  .set("spark.kryo.registrator", "com.mypackage.AvroKryoRegistrator")

AvroKryoRegistrator就是这样的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM