MSCK REPAIR TABLE 在幕后做了啥,为啥这么慢?
Posted
技术标签:
【中文标题】MSCK REPAIR TABLE 在幕后做了啥,为啥这么慢?【英文标题】:What does MSCK REPAIR TABLE do behind the scenes and why it's so slow?MSCK REPAIR TABLE 在幕后做了什么,为什么这么慢? 【发布时间】:2019-05-09 02:36:07 【问题描述】:我知道MSCK REPAIR TABLE
使用外部表的当前分区更新元存储。
为此,您只需在表的根文件夹上执行ls
(假设该表仅按一列分区),并获取其所有分区,显然是
但在实践中,该操作可能需要非常长时间来执行(甚至timeout if ran on AWS Athena)。
所以我的问题是,MSCK REPAIR TABLE
实际上在幕后做了什么,为什么?
MSCK REPAIR TABLE 如何找到分区?
相关的附加数据:
我们的数据都在 S3 上,在 EMR (Hive) 或 Athena (Presto) 上运行时都很慢,表中有大约 450 个分区,每个分区平均有 90 个文件,总共 3 GB一个分区,文件是 Apache parquet 格式
【问题讨论】:
cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL 提到了ALTER TABLE RECOVER PARTITIONS
。它只是MSCK
的别名还是做的工作更少?
@PiotrFindeisen 似乎只是 EMR 的等效命令。
据我所知,它列出了所有分区文件并收集了一些关于它们的元数据。如果您有 450 个分区和每个分区 90 个文件,它可能会对 s3 进行 40500 次调用以分别获取每个文件大小。我不确定它是否不止于此,但如果确实如此,它可能还会对文件进行一些统计分析。如果是这种情况,您可以尝试使用此选项:SET hive.stats.autogather=false;具体需要多长时间?我们谈论的是几分钟还是几个小时?几分钟不会让我震惊。
【参考方案1】:
你是对的,它读取目录结构,从中创建分区,然后更新配置单元元存储。事实上,最近,该命令也得到了改进,可以从 Metastore 中删除不存在的分区。您给出的示例非常简单,因为它只有一级分区键。考虑具有多个分区键的表(2-3 个分区键在实践中很常见)。 msck repair
将不得不对表目录下的所有子目录进行全树遍历,解析文件名,确保文件名有效,检查分区是否已经存在于元存储中,然后添加Metastore 中唯一不存在的分区。请注意,文件系统上的每个列表都是对名称节点的 RPC(在 HDFS 的情况下)或在 S3 或 ADLS 的情况下的 Web 服务调用,这可能会增加大量时间。此外,为了确定分区是否已经存在于 Metastore 中,它需要完整列出 Metastore 知道的表的所有分区。这两个步骤都可能会增加在大型表上执行命令所花费的时间。最近 Hive 2.3.0 显着提高了 msck 修复表的性能(有关更多详细信息,请参阅 HIVE-15879)。您可能需要调整 hive.metastore.fshandler.threads
和 hive.metastore.batch.retrieve.max
以提高命令的性能。
【讨论】:
谢谢!我很好奇,为什么即使在我只有 1 列部分分区的表中,操作也需要这么长时间?从阅读源代码来看,似乎只需要阅读第一级,即 450 个文件(目录)。 其实你是对的。 msck 在大于分区数的级别上进行了不必要的列表。这可以改进。我为此创建了 HIVE-21040。 非常感谢您使用源代码进行验证,找到并打开 Jira!如果您能更新您的答案,那就太好了,因为大多数人都不会费心阅读 cmets... 值得注意的是MSCK REPAIR
会选择新的路径来执行ADD PARTITION
,但不是相反:如果先前存在的partition
的路径被删除然后运行@ 987654329@won't achieveDROP PARTITION
的效果;这必须手动完成。另请参阅this 常见陷阱以上是关于MSCK REPAIR TABLE 在幕后做了啥,为啥这么慢?的主要内容,如果未能解决你的问题,请参考以下文章
Pyspark 中是不是有等效于 SQL 的 MSCK REPAIR TABLE 的方法
对于小型数据集,AWS Athena MSCK REPAIR TABLE 花费的时间太长