我有一个Spark作业(在CDH 5.5.1中)加载两个Avro文件(两者都使用相同的模式),将它们组合起来制作一个DataFrame(也使用相同的模式),然后将它们写回Avro。 / p>
作业明确地比较两个输入模式以确保它们是相同的。
这用于将现有数据与一些更新相结合(因为文件是不可变的)。然后我用新的组合文件替换原始文件,方法是在HDFS中重命名。
但是,如果我重复更新过程(即尝试向以前更新的文件添加一些进一步的更新),则作业将失败,因为模式现在不同了!发生了什么事?
答案 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)