Spark SQL - Hive“无法覆盖表”解决方法

Posted

技术标签:

【中文标题】Spark SQL - Hive“无法覆盖表”解决方法【英文标题】:Spark SQL - Hive "Cannot overwrite table" workaround 【发布时间】:2020-08-25 14:30:06 【问题描述】:

我正在使用 PySpark 和 Hive 开发 Spark 集群。

我在这里看到了很多关于“无法覆盖正在读取的表”Hive 错误的问题。我知道这来自 Hive 本身的工作方式,我们计划为此迁移到 Kudu:但现在我需要完成 Hive 的工作。 我找到了一些解决方案,几乎都依赖于“打破数据沿袭”的原则:

保存在临时表上,读回然后保存在右表上 检查数据帧

和类似的。我不想使用它们主要是因为它们在大型数据集上效率不高,所以我想出了这个:

bananaDF = spark.sql("select * from banana")
// hundreds of trasformations - no actions
bananaDF.write.mode("overwrite").saveAsTable("banana_temp")
spark.sql("DROP TABLE IF EXISTS banana")
spark.sql("ALTER TABLE banana_temp RENAME TO banana")

基本上,我只是

将更新后的表写入临时表 删除原始表 重命名临时表以匹配原始名称

使用这种方法,我只写一次数据,并且 drop-rename 部分相当有效(3K 记录表大约需要 1 秒)。 既然我知道我在编码方面并不那么出色......有人能发现这有什么问题吗?这似乎是一个简单的解决方法,但我在 Internet 上没有找到类似的东西(这让我非常怀疑)。

谢谢!

【问题讨论】:

【参考方案1】:

为什么不使用插入覆盖?尽管您的方式可能有效,但它不如使用 Hive 中声明的方法那么健壮。此外,这将减少表文件存储在 s3 等 blob 存储中的任何可能的位置漂移。

Standard syntax:
INSERT OVERWRITE TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] select_statement1 FROM from_statement;

Hive 文档:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DML

另一个很酷的选择是只使用 delta 而不是 hive,如果您在 databricks 环境中工作,这非常简单。这样做的原因是它允许通过 upsert 更快地插入。在此处查看更多信息:https://databricks.com/blog/2019/03/19/efficient-upserts-into-data-lakes-databricks-delta.html

【讨论】:

我仍然需要测试它,但我相信我无法从 Spark 插入覆盖。根据我在网上搜索的了解,Spark 是问题所在。同时,我发现了一个类似的问题(和答案)here。一旦有时间尝试您的建议,我会尽快更新您的信息。发送

以上是关于Spark SQL - Hive“无法覆盖表”解决方法的主要内容,如果未能解决你的问题,请参考以下文章

Spark 实践 | Hive SQL 迁移 Spark SQL 在滴滴的实践

Hive进阶-- Hive SQLSpark SQL和 Hive on Spark SQL

Spark,Hive SQL - 实现窗口功能?

Hive SQL迁移Spark SQL在滴滴的实践

Hive进阶-- Hive SQLSpark SQL和 Hive on Spark SQL

hive/spark写入保存出现小文件过多的解决