Hive查询生成多个小文件

时间:2016-02-10 04:00:30

标签: hadoop hive

我有2个hive表作为源。说

  • DEV.INPUT_01
  • DEV.INPUT_02

我还有一个表作为DEV.TARGET。我想将数据加载到此表中以获取上述2个输入表。我拥有的HQL是:

insert overwrite table DEV.TARGET partition(c30)
select
   c1
  ,c2
  ,c3
  ,c4
  ,c5
  ,c6
  ,c7
  ,c8
  ,c9
  ,c10
  ,c11
  ,c12
  ,c13
  ,c14
  ,c15
  ,c16
  ,c17
  ,c18
  ,c19
  ,c20
  ,c21
  ,c22
  ,c23
  ,c24
  ,c25
  ,c26
  ,c27
  ,c28
  ,c29
  ,c30
from
  DEV.SOURCE_01 t1 left join
  DEV.SOURCE_02 t2 on
  t1.tab_id = t2.tab_id;

查询工作正常。映射器数量为700,减速器数量为400.

问题在于以上查询每个分区生成400个文件,每个文件的大小约为200K。

我尝试过多个参数组合:

设置1

set hive.exec.reducers.bytes.per.reducer=256000000;

结果1 减少数量减少到100,因此每个分区生成100个文件。

设置2

set hive.merge.mapredfiles=true;
set hive.merge.size.per.task=256000000;
set hive.merge.smallfiles.avgsize=256000000;

结果2 以上设置启动了2个MR步骤,结果相同。

设置3

set mapred.reduce.tasks=40;

结果3

  • 文件数量减少到40(预期)
  • 查询性能下降了3倍(原始查询降低到20分钟,使用此设置需要55分钟)。
  • 另一个问题是此设置的数据大小。随着数据的增长,此设置开始降级更多,因此难以管理。

问题如何生成128M大小的文件?

3 个答案:

答案 0 :(得分:0)

我不认为您可以生成特定大小的文件作为Hive输出。 但是,您可以通过分区来实现其中的一部分

这个SO问题的答案解释了如何跨文件分割数据

Hive -- split data across files

答案 1 :(得分:0)

请设置以下属性

set hive.optimize.index.filter=true; 
set hive.exec.orc.skip.corrupt.data=true;
set hive.vectorized.execution.enabled=true;
set hive.compute.query.using.stats=true;
set stats.reliable=true; 
set hive.optimize.sort.dynamic.partition=true;
set hive.optimize.ppd=true;
set hive.optimize.ppd.storage=true;
set hive.merge.mapredfiles=true;
set hive.merge.mapfile=true ;
set hive.hadoop.supports.splittable.combineinputformat=true;
set hive.exec.compress.output=true;

我试图找到确切的设置组合对我有用。但他们一起只为我工作

答案 2 :(得分:0)

如果要减少HDFS中的分区文件数,则需要使用Hive参数限​​制块大小。例如,群集中的块大小配置为128M:

SET dfs.blocksize = 134217728;

(上面的二进制数) 有了它,您将理清小分区文件问题