如何避免Hive暂存区写入云端

Sum*_*rty 2 hadoop hive google-cloud-storage apache-spark

我必须经常将 Dataframe 编写为 Hive 表。

df.write.mode('overwrite').format('hive').saveAsTable(f'db.{file_nm}_PT')
Run Code Online (Sandbox Code Playgroud)

或者使用 Spark SQL 或 Hive SQL 将一张表复制到另一张表作为备份。

INSERT OVERWRITE TABLE db.tbl_bkp PARTITION (op_cd, rpt_dt)
SELECT * FROM db.tbl;
Run Code Online (Sandbox Code Playgroud)

问题是:写入 hive_saging_directory 需要总时间的 25%,而 75% 或更多时间用于将 ORC 文件从暂存目录移动到最终分区目录结构。

21/11/13 00:51:25 INFO hive.ql.metadata.Hive: New loading path = gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2019-10-24 with partSpec {rpt_dt=2019-10-24}
21/11/13 00:51:56 INFO hive.ql.metadata.Hive: Replacing src:gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2018-02-18/part-00058-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, dest: gs://sam_tables/teradata/tbl_bkp/rpt_dt=2018-02-18/part-00058-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, Status:true
21/11/13 00:51:56 INFO hive.ql.metadata.Hive: New loading path = gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2018-02-18 with partSpec {rpt_dt=2018-02-18}
21/11/13 00:52:31 INFO hive.ql.metadata.Hive: Replacing src:gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2019-01-29/part-00046-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, dest: gs://sam_tables/teradata/tbl_bkp/rpt_dt=2019-01-29/part-00046-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, Status:true
21/11/13 00:52:31 INFO hive.ql.metadata.Hive: New loading path = gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2019-01-29 with partSpec {rpt_dt=2019-01-29}
21/11/13 00:53:09 INFO hive.ql.metadata.Hive: Replacing src:gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2020-08-01/part-00020-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, dest: gs://sam_tables/teradata/tbl_bkp/rpt_dt=2020-08-01/part-00020-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, Status:true
21/11/13 00:53:09 INFO hive.ql.metadata.Hive: New loading path = gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2020-08-01 with partSpec {rpt_dt=2020-08-01}
21/11/13 00:53:46 INFO hive.ql.metadata.Hive: Replacing src:gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2021-07-12/part-00026-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, dest: gs://sam_tables/teradata/tbl_bkp/rpt_dt=2021-07-12/part-00026-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, Status:true
21/11/13 00:53:46 INFO hive.ql.metadata.Hive: New loading path = gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2021-07-12 with partSpec {rpt_dt=2021-07-12}
21/11/13 00:54:17 INFO hive.ql.metadata.Hive: Replacing src:gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2022-01-21/part-00062-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, dest: gs://sam_tables/teradata/tbl_bkp/rpt_dt=2022-01-21/part-00062-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, Status:true
21/11/13 00:54:17 INFO hive.ql.metadata.Hive: New loading path = gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2022-01-21 with partSpec {rpt_dt=2022-01-21}
21/11/13 00:54:49 INFO hive.ql.metadata.Hive: Replacing src:gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2018-01-20/part-00063-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, dest: gs://sam_tables/teradata/tbl_bkp/rpt_dt=2018-01-20/part-00063-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, Status:true
21/11/13 00:54:49 INFO hive.ql.metadata.Hive: New loading path = gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2018-01-20 with partSpec {rpt_dt=2018-01-20}
21/11/13 00:55:22 INFO hive.ql.metadata.Hive: Replacing src:gs://sam_tables/teradata/tbl_bkp/.hive-staging_hive_2021-11-12_23-26-38_441_6664318328991520567-1/-ext-10000/rpt_dt=2019-09-01/part-00037-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, dest: gs://sam_tables/teradata/tbl_bkp/rpt_dt=2019-09-01/part-00037-95ee77f0-4e27-4765-a454-e5009c4f33f3.c000, Status:true
Run Code Online (Sandbox Code Playgroud)

此操作在实际 HDFS 上相当快,但在 Google Cloud Blob 上,此重命名实际上是复制粘贴 Blob,并且非常慢。

我听说过直接路径写入,请问你们能建议如何做到这一点吗?

Fur*_*ine 5

(不是这样)简短的回答

情况很复杂。非常复杂。我想写一个简短的答案,但我可能会在几个点上被误导。相反,我将尝试对很长的答案进行简短的总结。

  • Hive 使用暂存目录有一个很好的理由:原子性。您不希望用户在重写表时读取表,因此您可以在暂存目录中写入数据,并在完成后重命名该目录,如下所示
  • 问题是:云存储是“对象存储”,而不是像HDFS这样的“分布式文件系统”,因此一些操作(例如文件夹重命名)可能会慢很多
  • 每个云都有自己的存储实现,有自己的特殊性和缺点,随着时间的推移,他们甚至提出新的变体来克服其中一些缺点(例如,Azure 有 3 种不同的存储变体:Blob 存储、Datalake Storage Gen 1 和 Gen 2)。
  • 因此,一种云上的最佳解决方案不一定是另一种云上的最佳解决方案。
  • 各种云存储的 FileSystem API 实现是 Spark 使用的 Hadoop 发行版的一部分。因此,您可用的解决方案还取决于您的 Spark 安装使用的 Hadoop 版本。
  • 仅限 Azure/GCS:您可以尝试设置[此选项]:( https://spark.apache.org/docs/3.1.1/cloud-integration.html#configuring ): spark.hadoop.mapreduce.fileoutputcommitter.algorithm.version 2。它比 更快,v1 但也不推荐,因为它不是原子的,因此在部分失败的情况下不太安全
  • v2目前是 Hadoop 中的默认值,但Spark 3 将其恢复为v1默认值,并且Hadoop 社区中存在一些讨论以弃用它并v1再次设置为默认值。
  • 还有一些正在进行的开发,基于为 S3 完成的类似输出提交器,为 Azure 和 GCS 编写更好的输出提交器

  • 或者,您可以尝试切换到云优先格式,例如 Apache Iceberg、Apache Hudi 或 Delta Lake。
  • 我对这些还不是很熟悉,但快速浏览一下Delta Lake 的文档后,我确信他们必须处理相同类型的问题(云存储不是真正的文件系统),并且根据您所在的云,它可能需要额外的配置,尤其是在 GCP 上,该功能被标记为实验性的
  • 编辑: Apache Iceberg 没有这个问题,因为它使用元数据文件指向真实的数据文件位置。因此,对表的更改是通过对单个元数据文件进行原子更改来提交的。
  • 我对 Apache Hudi 不是很熟悉,我找不到任何关于它们处理此类问题的提及。我必须进一步深入研究他们的设计架构才能确定。

现在,对于长答案,也许我应该写一篇博客文章......完成后我会将其发布在这里。