在写入Avro时,Spark会更改架构

时间:2016-07-26 07:52:33

标签: apache-spark avro cloudera-cdh spark-avro

我有一个Spark作业(在CDH 5.5.1中)加载两个Avro文件(两者都使用相同的模式),将它们组合起来制作一个DataFrame(也使用相同的模式),然后将它们写回Avro。 / p>

作业明确地比较两个输入模式以确保它们是相同的。

这用于将现有数据与一些更新相结合(因为文件是不可变的)。然后我用新的组合文件替换原始文件,方法是在HDFS中重命名。

但是,如果我重复更新过程(即尝试向以前更新的文件添加一些进一步的更新),则作业将失败,因为模式现在不同了!发生了什么事?

1 个答案:

答案 0 :(得分:2)

这是由于spark-avro包的行为造成的。

写入Avro时,spark-avro会将所有内容写为给定类型的联合以及null选项。

换句话说,"string"变为["string", "null"],因此每个字段都可以为空。

如果您的输入模式已经只包含可空字段,那么这个问题就不会显而易见了。

在spark-avro页面上没有提及,但在某些Cloudera documentation中被描述为spark-avro的限制之一:

  

由于Spark正在转换数据类型,请注意以下事项:

     
      
  • 枚举类型被删除 - Avro枚举类型在读入Spark时会成为字符串,因为Spark不支持   枚举类型。
  •   
  • 输出中的联合 - Spark将所有内容写为给定类型的联合以及null选项。
  •   
  • Avro架构更改 - Spark将所有内容都读入内部表示。即使你只是阅读然后写入数据,   输出的架构将有所不同。
  •   
  • Spark模式重新排序 - Spark在将它们写入磁盘时重新排序其模式中的元素,以便元素存在   分区是最后的元素。
  •   

另见github问题:(spark-avro 92