apache-spark - 为 impala 表无缝覆盖底层 parquet 数据
问题描述
我有一个由另一个团队使用的镶木地板文件支持的 Impala 表。每天我都会运行一个批处理 Spark 作业,它会覆盖现有的 parquet 文件(创建新数据集,现有文件将被删除并创建新文件)
我们的 Spark 代码如下所示
dataset.write.format("parquet").mode("overwrite").save(path)
在此更新期间(覆盖 parquet 数据文件,然后覆盖REFRESH
Impala 表),如果有人访问该表,那么他们最终会出现错误,指出基础数据文件不存在。
是否有任何解决方案或解决方法可用于此问题?因为我不希望其他团队在访问表时在任何时间点看到错误。
也许我可以将新的数据文件写入不同的位置,然后让 Impala 表指向那个位置?
解决方案
您看到的行为是因为 Impala 的设计方式。Impala 从 HMS 获取表的元数据,例如表结构、分区详细信息、HDFS 文件路径以及来自 NameNode 的相应 HDFS 文件路径的块详细信息。所有这些详细信息都由 Catalog 获取,并将分布在 Impala 守护程序中以供执行。
当表的底层文件被删除并在 Impala 外部写入新文件时,需要执行 REFRESH 以便获取新文件详细信息(例如文件和相应的块详细信息)并跨守护进程分发。这样,Impala 就会知道新写入的文件。
由于您正在覆盖文件,Impala 查询将无法找到它知道的文件,因为它们已经被删除并且正在写入新文件。这是一个预期的事件。
作为解决方案,您可以执行以下操作之一,
- 将新文件追加到表的同一 HDFS 路径中,而不是覆盖。这样,在表上运行的 Impala 查询仍然会返回结果。然而,结果将只是较旧的数据(因为 Impala 还不知道新文件),但在发生覆盖期间将避免您所说的错误。在表的目录中创建新文件后,您可以执行 HDFS 操作以删除这些文件,然后为该表执行 Impala REFRESH 语句。
或者
- 正如您所说,您可以在不同的 HDFS 路径中写入新的 parquet 文件,一旦写入完成,您可以 [删除旧文件,将新文件移动到表的实际 HDFS 路径中,然后是 REFRESH ]或[对表发出 ALTER 语句以修改指向新目录的表数据的位置]。如果这是一个日常过程,您可能必须通过一个脚本来实现这一点,该脚本在 Spark 完成的成功写入过程中运行,通过将目录(新目录和旧目录)作为参数传递。
希望这可以帮助!
推荐阅读
- python - 使用python opencv进行图像隐写术,重建嵌入图像非常嘈杂
- f# - 运行与纯 Mono 等效的 `dotnet test`
- stripe-payments - iOS/Firebase - Stripe Connect 账户验证
- reactjs - jsPDF , TypeError: pdf.fromHTML is not a function in REACT
- c - 为什么拔掉电缆时revents是0?
- matlab - 如何从matlab表中删除只有零的行?
- mysql-workbench - 你可以在mysql工作台中恢复一个表吗?
- r - R:按颜色和ID选择
- python - 在运行 pdb 时,它显示已返回空列表
- php - 即使我使用 TLS,启用 SMTPAuth 和 SMTPAutoTLS 以及端口 25 和 465,“SMTP 连接()失败”仍然存在。我使用 HotsGator