如何手动将分区详细信息添加到 hive Metastore 表中?

如何解决如何手动将分区详细信息添加到 hive Metastore 表中?

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

现在,我想设置一个外部表,使用 MySQL 作为 Hive Metastore。我目前面临着发现所有 1.4 分区永远需要的已知问题。众所周知,MSCK REPAIR TABLE my_table 不在画面中。我生成了一个长查询(大约 400 MB),其中包含这样的查询


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 ''

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

  1. Spark 一次只做一个分区。
  2. Spark 似乎会检查每个路径是否存在。

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

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

  1. 如何通过直接进入 Hive Metastore 表来创建带有分区的外部表?
  2. 如何通过对 Hive 元存储表进行直接更新插入查询来管理外部表分区?

是否有很好的资源可以用来了解 Metastore 中的后备表。我觉得手动插入会快得多。谢谢。

解决方法

我认为这里的核心问题是你有太多的分区。分区通常应在基数较低的列上进行(与记录总数相比,不同值的数量相对较少)。通常,您希望在拥有较少数量的大文件而不是大量小文件方面犯错。

在您的示例中,假设每个日期有很多记录,date 可能是一个很好的分区列。如果 event_id 有大量不同的值,则不适合进行分区。只需将其保留为未分区的列即可。

对高基数列进行分区的另一种方法是分桶。这将分桶列的相似值分组,因此它们位于同一个文件中,但不会将每个值拆分到单独的文件中。 AWS Athena docs 对该概念有很好的概述。

,

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

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

    set hive.stats.autogather=false;

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

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

相关票证有HIVE-18743HIVE-19489HIVE-17478

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?