为 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 数据的主要内容,如果未能解决你的问题,请参考以下文章