Spark AVRO 与 BigQuery 兼容
Posted
技术标签:
【中文标题】Spark AVRO 与 BigQuery 兼容【英文标题】:Spark AVRO compatible with BigQuery 【发布时间】:2017-12-18 09:47:00 【问题描述】:我正在尝试在 Hive 中创建一个外部表,并在 BigQuery 中创建另一个表,使用存储在 Google Storage 中的 Avro 格式的相同数据,使用 Spark 编写。
我正在使用带有 Spark 2.2.0、Spark-avro 4.0.0 和 Hive 2.1.1 的 Dataproc 集群
Avro 版本/包之间存在相同的差异,但如果我使用 Hive 创建表,然后使用 Spark 编写文件,我可以在 Hive 中看到它们。
但 BigQuery 不同,它可以读取 Hive Avro 文件,但不能读取 Spark Avro 文件。
错误:
The Apache Avro library failed to parse the header with the follwing error: Invalid namespace: .someField
搜索了一下错误,问题是 Spark Avro 文件与 Hive/BigQuery Avro 文件不同。
我不知道如何解决这个问题,可能是在 Spark 中使用不同的 Avro 包,但我还没有找到哪个与所有系统兼容。
另外我想避免棘手的解决方案,比如在 Hive 中创建一个临时表并使用 insert into ... select * from ...
创建另一个我会写很多数据,我想避免这种解决方案
任何帮助将不胜感激。谢谢
【问题讨论】:
错误是“无效的命名空间:.someField”。 “.someField”是正确的全名吗? avro.apache.org/docs/current/spec.html#names 这是另一个名称,但它正是其中一个字段的名称。其实就是一个 Array of Struct 字段的名称。 Avro 版本之间的架构定义似乎有些差异。 【参考方案1】:错误消息由 BigQuery 使用的 C++ Avro 库引发。 Hive 可能使用 Java Avro 库。 C++ 库不喜欢命名空间以“.”开头。
这是来自库的代码:
if (! ns_.empty() && (ns_[0] == '.' || ns_[ns_.size() - 1] == '.' || std::find_if(ns_.begin(), ns_.end(), invalidChar1) != ns_.end()))
throw Exception("Invalid namespace: " + ns_);
【讨论】:
很高兴知道,谢谢。但是问题依然存在,不知道有没有办法让 Spark Avro 与 BigQuery Avro 兼容? 您可以将命名空间更改为不以“.”开头吗?然后 Spark 和 BigQuery 都应该能够读取它。 我想要,但我不能,我的字段没有“。”一开始,是 Spark 的 Avro 写了那个“。” 我明白了。根据 avro 规范,听起来应该允许空命名空间:avro.apache.org/docs/1.8.2/spec.html#names。因此,您可以向 Avro 库提交错误。您还可以通过 issuetracker.google.com/issues/… 提交 BigQuery 问题。【参考方案2】:Spark-avro 有额外的选项recordNamespace
来设置根命名空间,所以它不会从.
开始。
https://github.com/databricks/spark-avro/blob/branch-4.0/README-for-old-spark-versions.md
【讨论】:
【参考方案3】:想知道你是否曾经找到过这个问题的答案。
我也看到了同样的情况,我正在尝试将数据加载到 bigquery 表中。该库首先以 avro 格式将数据加载到 GCS 中。架构也有一个结构数组,命名空间是.
【讨论】:
我没找到。现在我正在以 JSON 格式编写数据,但我想在某个时候为 AVRO 更改它。以上是关于Spark AVRO 与 BigQuery 兼容的主要内容,如果未能解决你的问题,请参考以下文章
通过 CLI 将存储桶中的 AVRO 加载到具有日期分区的 BigQuery 中
BigQuery - use_avro_logical_types 在 python 脚本中不起作用