使用spark-avro在记录中跳过字段

时间:2016-11-03 15:29:06

标签: apache-spark avro spark-avro

更新:spark-avro软件包已更新以支持此方案。 https://github.com/databricks/spark-avro/releases/tag/v3.1.0

我有一个由我控制之外的第三方创建的AVRO文件,我需要使用spark进行处理。 AVRO模式是一个记录,其中一个字段是混合联合类型:

{    
    "name" : "Properties",                              
    "type" : {                                          
    "type" : "map",                                   
    "values" : [ "long", "double", "string", "bytes" ]
}                                                   

spark-avro读者不支持此功能:

  

除了上面列出的类型外,它还支持读取三种类型的联合类型:   union(int,long)   联合(浮动,双)   union(something,null),其中某些内容是上面列出的受支持的Avro类型之一,或者是支持的联合类型之一。

阅读AVRO的模式演变和解决方案,我希望能够通过指定省略此字段的不同读取器模式来跳过有问题的字段时读取文件。 根据{{​​3}},它应该有效:

  

如果作者的记录中包含一个名称不在读者记录中的字段,则该字段的作者值将被忽略。

所以我使用

进行了修改
 val df = sqlContext.read.option("avroSchema", avroSchema).avro(path)

avroSchema是完全相同的架构,编写者使用,但没有问题字段。

但是我仍然得到关于混合联合类型的相同错误。

AVRO支持这种架构演变的场景吗?与avro-spark? 还有另一种方法来实现我的目标吗?

更新: 我已经使用Apache Avro 1.8.1测试了相同的场景(实际上是相同的文件)并且它按预期工作。然后它必须专门与spark-avro。任何想法?

1 个答案:

答案 0 :(得分:5)

更新:spark-avro软件包已更新以支持此方案。 https://github.com/databricks/spark-avro/releases/tag/v3.1.0

这实际上并没有回答我的问题,而是针对同一问题的不同解决方案。

由于目前spark-avro没有此功能(请参阅我对该问题的评论) - 我使用了avro' org.apache.avro.mapreduce和spark newAPIHadoopFile。这是一个简单的例子:

val path = "..."
val conf = new SparkConf().setAppName("avro test")
  .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer") 
val sc = new SparkContext(conf)

val avroRdd = sc.newAPIHadoopFile(path,
  classOf[AvroKeyInputFormat[GenericRecord]],
  classOf[AvroKey[GenericRecord]],
  classOf[NullWritable])
与spark-avro相反,官方avro libs支持混合联合类型和模式演变。