【问题标题】:Spark SQL - Hive "Cannot overwrite table" workaroundSpark SQL - Hive“无法覆盖表”解决方法
【发布时间】: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 上没有找到类似的东西(这让我非常怀疑)。

谢谢!

【问题讨论】:

    标签: apache-spark hadoop pyspark hive apache-spark-sql


    【解决方案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。一旦有时间尝试您的建议,我会尽快更新您的信息。发送
    猜你喜欢
    • 2020-08-06
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    相关资源
    最近更新 更多