2016-07-26 93 views
1

我有一个加载两个Avro文件(都具有相同架构)的Spark作业(在CDH 5.5.1中),然后将它们组合起来制作一个DataFrame(也具有相同的架构),然后把它们写回Avro。Spark在写入Avro时会更改架构

作业显式比较两个输入模式以确保它们相同。

这是用来结合现有的数据和几个更新(因为文件是不可变的)。然后我用HDFS中的新文件替换原来的文件。

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

回答

2

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

在写入Avro时,spark-avro将所有类型的对象都写为null,

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

如果您的输入模式已经只包含空字段,那么这个问题就不会变得明显。

这不是火花阿夫罗页提到,但在某些Cloudera documentation被描述为火花阿夫罗的局限性之一:

由于火花是转换数据类型,注意以下:

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

又见这个问题的GitHub(spark-avro 92