为 impala 表无缝覆盖底层 parquet 数据

Posted

技术标签:

【中文标题】为 impala 表无缝覆盖底层 parquet 数据【英文标题】:Override underlying parquet data seamlessly for impala table 【发布时间】:2020-03-10 04:44:42 【问题描述】:

我有一个 Impala 表,它由另一个团队使用的镶木地板文件支持。 我每天运行一个批处理 Spark 作业,覆盖现有 parquet 文件(创建新数据集,现有文件将被删除并创建新文件)

我们的 Spark 代码如下所示

dataset.write.format("parquet").mode("overwrite").save(path)

在此更新期间(覆盖 parquet 数据文件,然后覆盖 REFRESH Impala 表),如果有人访问该表,那么他们最终会收到错误消息,指出基础数据文件不存在。

对于这个问题是否有任何可用的解决方案或解决方法?因为我不希望其他团队在访问表时在任何时间点看到错误。

也许我可以将新数据文件写入不同的位置,然后让 Impala 表指向该位置?

【问题讨论】:

你能解释一下“覆盖镶木地板数据文件”吗?您是先删除 parquet 文件,然后使用 Spark 在同一目录中写入新的 Parquet 数据文件吗? @Gomz 谢谢,编辑了我的问题并添加了更多信息 "..他们最终会出现错误.." -- 您能否添加运行查询时遇到的确切错误? 【参考方案1】:

您所看到的行为是因为 Impala 的设计工作方式。 Impala 从 HMS 获取表的元数据,例如表结构、分区详细信息、HDFS 文件路径以及来自 NameNode 的相应 HDFS 文件路径的块详细信息。所有这些详细信息都由 Catalog 获取,并将分布在 Impala 守护程序中以供其执行。

当表的底层文件被删除并在 Impala 外部写入新文件时,需要执行 REFRESH 以便获取新文件详细信息(例如文件和相应的块详细信息)并跨守护进程分发。这样,Impala 就会知道新写入的文件。

由于您正在覆盖文件,Impala 查询将无法找到它知道的文件,因为它们已被删除并且正在写入新文件。这是一个预期的事件。

作为一种解决方案,您可以执行以下操作之一,

    将新文件追加到表的同一 HDFS 路径中,而不是覆盖。这样,在表上运行的 Impala 查询仍会返回结果。但是,结果将只是旧数据(因为 Impala 尚不知道新文件),但在发生覆盖期间将避免您所说的错误。在表的目录中创建新文件后,您可以执行 HDFS 操作以删除这些文件,然后为该表执行 Impala REFRESH 语句。

    如您所说,您可以在不同的 HDFS 路径中写入新的 parquet 文件,一旦写入完成,您可以 [删除旧文件,将新文件移动到表的实际 HDFS 路径中, 后跟 REFRESH] OR [对表发出 ALTER 语句以修改指向新目录的表数据的位置]。如果这是一个日常过程,您可能必须通过一个脚本来实现这一点,该脚本在 Spark 完成的成功写入过程中运行,通过将目录(新目录和旧目录)作为参数传递。

希望这会有所帮助!

【讨论】:

以上是关于为 impala 表无缝覆盖底层 parquet 数据的主要内容,如果未能解决你的问题,请参考以下文章

Parquet 支持的 Hive 表:Impala 中不可查询的数组列

通过 Impala 的 Parquet 压缩类型

Impala - 替换表分区中的所有数据

Impala 中的表格压缩

为分区数据定义 Impala 表模式

在 CDH 集群之间复制 parquet 表