我已经看过各种spark和avro问题(包括How can I load Avros in Spark using the schema on-board the Avro file(s)?),但是这些解决方案对我来说都不适用于以下avro文件:
http://www.4shared.com/file/SxnYcdgJce/sample.html
当我尝试使用上面的解决方案读取avro文件时,我得到的错误是它不可序列化(spark java.io.NotSerializableException:org.apache.avro.mapred.AvroWrapper)。
如何设置spark 1.1.0(使用scala)来读取此示例avro文件?
- 更新 -
答案 0 :(得分:4)
尝试阅读Avro文件时遇到了同样的问题。原因是AvroWrapper没有实现java.io.Serializable
接口。
解决方案是使用org.apache.spark.serializer.KryoSerializer
。
import org.apache.spark.SparkConf
val cfg = new SparkConf().setAppName("MySparkJob")
cfg.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
cfg.set("spark.kryo.registrator", "com.stackoverflow.Registrator")
然而这还不够,因为我的类在Avro文件中也没有实现Serializable
。
因此,我添加了自己的registrator,扩展了KryoRegistrator
,并包含了chill-avro库。
class Registrator extends KryoRegistrator {
override def registerClasses(kryo: Kryo): Unit = {
kryo.register(classOf[MyClassInAvroFile], AvroSerializer.SpecificRecordBinarySerializer[MyClassInAvroFile])
kryo.register(classOf[AnotherClassInAvroFile], AvroSerializer.SpecificRecordBinarySerializer[AnotherClassInAvroFile])
}
}
然后我能够读取这样的文件:
ctx.hadoopFile("/path/to/the/avro/file.avro",
classOf[AvroInputFormat[MyClassInAvroFile]],
classOf[AvroWrapper[MyClassInAvroFile]],
classOf[NullWritable]
).map(_._1.datum())
答案 1 :(得分:2)
将序列化器编辑为kryo应该可以解决问题。
一种方法是在/etc/spark/conf/spark-defaults.conf中注释掉这一行:
spark.serializer org.apache.spark.serializer.KryoSerializer
答案 2 :(得分:1)
我的解决方案是在我的问题中使用spark 1.2和sparkSQL:
val person = sqlContext.avroFile("/tmp/person.avro")