解决Hive动态分区小文件过多问题

一、问题描述

  1. 为了支撑相应的业务需求,本次生产环境通过Hive SQL来完成动态插入分区表数据的脚本开发。但是,动态分区的插入往往会伴随产生大量的小文件的发生。而小文件产生过多的影响主要分为以下两种情况:
    (1) 从Hive的角度看,小文件会开很多map,一个map开一个JVM去执行,所以这些任务的初始化,启动,执行会浪费大量的资源,严重影响性能。
    (2)在HDFS中,每个小文件对象约占150byte,如果小文件过多会占用大量内存。这样NameNode内存容量严重制约了集群的扩展。
    所以,我们必须要解决上述小文件过多的情况,可以从输入、中间过程和输出来入手进行优化。

二、知识概括

  1. 简要描述动态分区
    所谓的动态分区,就是对分区表insert数据时候,数据库自动会根据分区字段的值,将数据插入到相应的分区中,Hive也提供了类似的机制,即动态分区。
·在PARTITION (month,day)中指定分区字段名即可;
·在SELECT子句的最后两个字段,必须对应前面PARTITION (month,day)中指定的分区字段,包括顺序。

[注意] hive使用动态分区,需要进行相应的配置。
2. 动态分区相关配置项介绍

● hive.exec.dynamic.partition
  ○ 默认值:false
  ○ 是否开启动态分区功能,默认为关闭状态
  ○ 使用动态分区,必须将该参数设置为true
● hive.exec.dynamic.partition.mode
  ○ 默认值为:strict
  ○ 动态分区的模式,默认为:strict,表示必须指定至少一个分区为静态分区。nonstrict模式表示允许所有的分区字段都可以动态分区。
  ○ 一般需要设置为nonstrict
● hive.exec.max.dynamic.partitions.pernode
  ○ 默认值为:100
  ○ 在每个执行的MR任务的节点上,最大可以创建多少个动态分区
  ○ 该参数根据实际数据情况来定
  ○ 比如:源数据中包含了一年的数据,即day字段有365个值,那么该参数就需要设置成大于365,如果使用默认值100,则会报错。
● hive.exec.max.dynamic.partitions
  ○ 在所有执行MR的节点上,最大一共可以创建多少个动态分区
  ○ 一般默认值足够,除非你的数据量非常大,需要创建的文件数大于100000,可以根据实际情况来调整
● hive.exec.max.created.files
  ○ 默认值为:100000
  ○ 整个MR job中,最大可以创建多少个hdfs文件
  ○ 一般默认值足够,除非你的数据量非常大,需要创建的文件数大于100000,可以根据实际情况来调整
● hive.error.on.empty.partition
  ○ 默认值为:false
  ○ 当有空分区生成时,是否抛出异常
  ○ 一般不需要设置

三、案例实操

  1. 本次优化的过程,所设置的参数主要涉及动态分区的参数配置以及减少map和reduce数量。
4. 调整参数减少Map数量
● 设置map输入合并小文件的相关参数:
#执行Map前进行小文件合并
#CombineHiveInputFormat底层是 Hadoop的 CombineFileInputFormat 方法
#此方法是在mapper中将多个文件合成一个split作为输入
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
#每个Map最大输入大小(这个值决定了合并后文件的数量)
set mapred.max.split.size=256000000;   -- 256M
#一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100000000;  -- 100M
#一个交换机下split的至少的大小(这个值决定了多个交换机上的文件是否需要合并)
set mapred.min.split.size.per.rack=100000000;  -- 100M
● 设置map输出和reduce输出进行合并的相关参数:
#设置map端输出进行合并,默认为true
set hive.merge.mapfiles = true;
#设置reduce端输出进行合并,默认为false
set hive.merge.mapredfiles = true;
#设置合并文件的大小
set hive.merge.size.per.task = 256000000;   -- 256M
#当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge
set hive.merge.smallfiles.avgsize=16000000;   -- 16M 

5. 减少Reduce的数量
#reduce 的个数决定了输出的文件的个数,所以可以调整reduce的个数控制hive表的文件数量,
#hive中的分区函数 distribute by 正好是控制MR中partition分区的,
#然后通过设置reduce的数量,结合分区函数让数据均衡的进入每个reduce即可。
#第二种是设置每个reduce的大小,Hive会根据数据总大小猜测确定一个reduce个数
set hive.exec.reducers.bytes.per.reducer=10240000000; -- 默认是1G,设置为10G
#执行以下语句,将数据均衡的分配到reduce中
set mapreduce.job.reduces=10;
insert into table A partition(dt)
select * from B
distribute by cast(rand()*100 as int);
解释:如设置reduce数量为10,则使用 rand(), 随机生成一个数 x % 10 ,
这样数据就会随机进入 reduce 中,防止出现有的文件过大或过小

6. 动态分区参数设置
set hive.exec.dynamic.partition = true;
set hive.exec.dynamic.partition.mode = nostrick;
set hive.exec.max.dynamic.partitions.pernode=5000;
set hive.exec.max.dynamic.partitions = 10000;
set hive.exec.max.created.files =1000000;

四、结果对比

  1. 未处理小文件前,小文件数量很多,截图如下:
    在这里插入图片描述
  2. 整体文件数如下图所示:
    在这里插入图片描述
  3. 处理小文件后,文件大小如下图所示:
    在这里插入图片描述
  4. 整体文件数如下图所示:
    在这里插入图片描述

五、总结
以上就是我本次对由动态分区插入产生大量的小文件的优化过程,采用动态分区参数设置和减少map和reduce数量并且加上使用distribute by cast(rand()*N as int) 随机分发的策略很好的解决集群小文件问题,起到了优化的作用。

  • 6
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
动态分区Hive中会导致创建过多分区文件动态分区是根据表的输入数据动态创建分区,而不需要提前知道所有分区。这种方式适用于有很多分区且无法提前预估新分区的情况。 [3] 在处理大量数据时,动态分区可能会导致分区文件过多问题。这是因为每个不同的分区值都会创建一个新的分区文件。当分区值的数量非常大时,就会产生大量的分区文件,可能会对性能和存储带来负面影响。 为了解决这个问题,可以考虑以下几个方法: 1. 调整数据的分区策略:如果可能的话,可以尝试减少分区的数量,或者调整分区键的范围,使得每个分区的数据量更加均匀。 2. 压缩分区文件:可以使用压缩算法对分区文件进行压缩,减少存储空间的占用。 3. 定期合并小文件:可以定期对小文件进行合并,减少文件数量,提高查询性能。 综上所述,动态分区Hive中可能会导致分区文件过多问题。可以通过调整分区策略、压缩分区文件或定期合并小文件解决这个问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [什么是hive的静态分区动态分区,它们又有什么区别呢?hive动态分区详解](https://blog.csdn.net/sinat_40572875/article/details/128062279)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *2* [什么是hive的静态分区动态分区hive动态分区详解](https://blog.csdn.net/weixin_39836604/article/details/126214513)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值