1

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

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

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

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

4

1 回答 1

4

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

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

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

如果您的输入模式已经只包含可为空的字段,则此问题不会变得明显。

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

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

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

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

于 2016-07-26T07:52:32.930 回答