Spark 在写入 Avro 时更改架构

DNA*_*DNA 1 avro apache-spark cloudera-cdh spark-avro

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

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

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

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

DNA*_*DNA 5

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

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

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

如果您的输入架构已仅包含可为空的字段,则此问题不会变得明显。

Spark-avro 页面上没有提到这一点,但在一些Cloudera 文档中被描述为 Spark-avro 的限制之一:

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

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

另请参阅此 github 问题:( spark-avro 92 )