如何手动将分区详细信息添加到配置单元元存储表中



在我的HDFS中,我已经按dateevent_id对数据进行了分区,并且拥有大约140万个镶木地板文件。今天,为了分析Apache Spark中的数据,我使用spark.read.parquet("/path/to/root/")。列出文件大约需要30分钟,我每次都要这样做,而且越来越烦人。

现在,我想设置一个外部表,使用MySQL作为配置单元元存储。我目前面临的问题是,发现所有1.4分区需要很长时间。众所周知,MSCK REPAIR TABLE my_table是不可能出现的。相反,我生成了一个长查询(大约400MB(,其中包含这个类似的查询


ALTER TABLE my_table ADD 
PARTITION (date = 'YYYY-MM-DD', event_id = "<some value>") LOCATION ''
PARTITION (date = 'YYYY-MM-DD', event_id = "<some value>") LOCATION ''
PARTITION (date = 'YYYY-MM-DD', event_id = "<some value>") LOCATION ''
...
PARTITION (date = 'YYYY-MM-DD', event_id = "<some value>") LOCATION ''
PARTITION (date = 'YYYY-MM-DD', event_id = "<some value>") LOCATION ''

已经3个小时了,它仍然只处理了不到100000个分区。我观察到了一些事情:

  1. Spark一次执行一个分区
  2. Spark似乎在检查每条路径是否存在

所有这些都增加了较长的运行时间。我已经搜索过了,但找不到如何禁用这两种操作。

因此,我想手动对MySQL数据库和Hive元存储的表执行SQL操作,以创建和管理表。我已经看过了,但一直无法弄清楚如何手动管理这些表。拜托,有人知道怎么做吗?具体来说,我想要以下内容:

  1. 如何通过直接进入配置单元元存储表来创建带有分区的外部表
  2. 如何通过对配置单元元存储表进行直接追加查询来管理外部表分区

有没有一个好的资源可以用来了解元存储中的备份表。我觉得手动插入会快得多。非常感谢。

我认为这里的核心问题是分区太多。分区通常应该在基数较低的列上进行(与记录总数相比,具有相对较少的不同值的列(。通常情况下,您希望错误地选择较小数量的大文件,而不是大量的小文件。

在您的示例中,假设每个日期都有许多记录,date可能是一个很好的分区列。如果event_id有大量不同的值,那么这不是一个很好的分区候选者。只需将其保留为未分区的列即可。

对于高基数列,分区的另一种选择是分段。这会对带框列的类似值进行分组,使它们位于同一文件中,但不会将每个值拆分到不同的文件中。AWS Athena文档对这个概念有一个很好的概述。

这可能是统计信息自动收集的问题。作为一种解决方法,请在恢复分区之前关闭hive.stats.autoather。

  1. 关闭统计信息自动收集:

    set hive.stats.autogather=false;

  2. 运行MSCK REPAIR或ALTER TABLE RECOVER PARTITIONS。

如果需要更新统计信息,则可以仅对新分区单独执行ANALYZE。

相关门票为HIVE-18743、HIVE-14849、HIVE-17478

最新更新