为 impala table 无缝覆盖底层镶木地板数据

Override underlying parquet data seamlessly for impala table

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

我们的 Spark 代码如下所示

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

在此更新期间(覆盖 parquet 数据文件,然后 REFRESH Impala table),如果有人访问 table 那么他们最终会报错说基础数据文件不存在。

是否有解决此问题的解决方案或变通方法?因为我不希望其他团队在访问 table.

时在任何时间点看到错误

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

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

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

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

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

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

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

希望对您有所帮助!