Hive 指定从配置单元插入生成的最小文件数

Hive 指定从配置单元插入生成的最小文件数,hive,mapreduce,hiveql,amazon-emr,hadoop-partitioning,Hive,Mapreduce,Hiveql,Amazon Emr,Hadoop Partitioning,我使用AWS EMR上的配置单元将查询结果插入到按日期分区的配置单元表中。虽然每天的总输出大小是相似的,但生成的文件数量会有所不同,通常在6到8之间,但有时它只创建一个大文件。我重新运行了几次查询,以防文件数量恰好受到集群中节点可用性的影响,但看起来是一致的 所以我的问题是 (a) 什么决定了生成的文件数量和 (b) 有没有办法指定每个文件的最小文件数或(甚至更好)最大大小?插入过程中生成的文件数。。。选择取决于在最终减速器上运行的进程数(如果在Tez上运行,则为最终减速器顶点)加上每个配置的减

我使用AWS EMR上的配置单元将查询结果插入到按日期分区的配置单元表中。虽然每天的总输出大小是相似的,但生成的文件数量会有所不同,通常在6到8之间,但有时它只创建一个大文件。我重新运行了几次查询,以防文件数量恰好受到集群中节点可用性的影响,但看起来是一致的

所以我的问题是 (a) 什么决定了生成的文件数量和
(b) 有没有办法指定每个文件的最小文件数或(甚至更好)最大大小?

插入过程中生成的文件数。。。选择取决于在最终减速器上运行的进程数(如果在Tez上运行,则为最终减速器顶点)加上每个配置的减速器的字节数

如果表是分区的,并且没有指定
分发依据
,那么在最坏的情况下,每个reducer会在每个分区中创建文件。这会在减压器上产生高压,并可能导致OOM异常

要确保还原程序每个只写入一个分区文件,请在查询末尾添加
distributed BY partition\u column

如果数据量太大,并且您希望使用更多的缩减器来提高并行性并在每个分区中创建更多的文件,请在分发方式中添加随机数,例如使用以下命令:
FLOOR(RAND()*100.0)%10
-它将通过随机10个存储桶来额外分发数据,因此每个分区中将有10个文件

最后,插入的句子如下所示:

INSERT OVERWRITE table PARTITION(part_col)
SELECT * 
  FROM src
DISTRIBUTE BY  part_col, FLOOR(RAND()*100.0)%10; --10 files per partition
此配置设置还影响生成的文件数:

set hive.exec.reducers.bytes.per.reducer=67108864; 
如果数据太多,配置单元将启动更多的还原程序,以处理每个还原程序上指定的每个还原程序不超过
字节的数据。还原程序越多-生成的文件越多。减少此设置可能会增加正在运行的还原程序的数量,并且每个还原程序将至少创建一个文件。如果分区列不在
分发依据
中,则每个reducer可以在每个分区中创建文件

要使长话短说,请使用

DISTRIBUTE BY  part_col, FLOOR(RAND()*100.0)%10 -- 10 files per partition
如果每个分区需要20个文件,请使用FLOOR(RAND()*100.0)%20;-如果您有足够的数据,这将保证每个分区至少有20个文件,但不能保证每个文件的最大大小。

每个减速机的字节数设置不能保证它是固定的最小文件数。文件数将取决于总数据大小/bytes.per.reducer此设置将保证每个文件的最大大小。

但最好使用一些均匀分布的键或低基数的组合,而不是随机的,因为在容器重新启动的情况下,rand()可能会为同一行生成不同的值,并可能导致数据重复或丢失(某些减速机输出中已存在的相同数据将再次分配给另一个减速机)。您可以在某些可用键上计算类似的函数,而不是
rand()
,以获得基数较低的大致均匀分布的键

您可以结合使用这两种方法:每个减速机的字节数限制+分发方式来控制最小文件数和最大文件大小


也请阅读关于使用
distributed by
在减速器之间均匀分布数据的回答:

谢谢,很高兴了解
distributed by
,尽管我最后在表定义中使用了
CLUSTER by
。对每种方法的优缺点有何看法?