hive动态分区遇见的问题记录

项目场景:

将hbase数据卸出到hive分区表:
项目场景:按省份分区(36个分区),数据量50亿,数据大小4T左右


使用动态分区时首先不要忘记的一些配置:

是否开启动态分区 hive.exec.dynamic.partition
动态分区是否使用严格模式 hive.exec.dynamic.partition.mode
MR总共可创建最大分区数 hive.exec.max.dynamic.partition.partitions (默认1000)以及当前节点可创建的最大分区数 hive.exec.max.dynamic.partition.partitions.pernode (默认100)

问题描述:

直接sql执行:

insert overwrite table test1 partition (prov_branch_code) select * from test2;

mapreduce执行4个多小时,map个数5501,reduce个数1099(默认的最大值),reduce有几个节点运行时间长。


原因分析:

数据偏移,有部分省份数据量大,造成部分节点运行缓慢


解决方案:

为了防止一个reduce处理写入一个分区导致速度严重降低,加入如下参数

SET hive.optimize.sort.dynamic.partition=false;。

又出现了新的问题: table_tmp表里面一共有4T的数据,一共可以分成36个分区,SQL运行的时候创建了5501个Mapper,0个Reducers。程序运行到一般左右的时候出现了以下的异常:

[Fatal Error] total number of created files now is 100385, which exceeds 100000. Killing the job.

并最终导致了SQL的运行失败。这个错误的原因是因为Hive对创建文件的总数有限制(hive.exec.max.created.files),默认是100000个,而这个SQL在运行的时候每个Map都会创建76个文件,对应了每个分区,所以这个SQL总共会创建5501 * 36 = 198036个文件,运行中肯定会出现上述的异常。为了能够成功地运行上述的SQL,最简单的方法就是加大hive.exec.max.created.files参数的设置。但是这有个问题,这会导致在hadoop中产生大量的小文件,因为source表的数据就4T,那么平均每个文件的大小=4T / 198036= 10.589MB,可想而知,十九万多个这么小的小文件对Hadoop来说是多么不好。那么有没有好的办法呢?有!

我们可以将dt相同的数据放到同一个Reduce处理,这样最多也就产生36个文件,将dt相同的数据放到同一个Reduce可以使用DISTRIBUTE BY dt实现,所以修改之后的SQL如下:

hive> insert overwrite table test partition(dt)
> select * from table_tmp
> DISTRIBUTE BY dt;
修改完之后的SQL
运行良好,并没有出现上面的异常信息,但是这里也有个问题,因为这36个分区的数据分布很不均匀,有些Reduce的数据有30多G,而有些Reduce只有几K,直接导致了这个SQL运行的速度很慢!

能不能将4T的数据均匀的分配给Reduce呢?可以!我们可以使用DISTRIBUTE BY rand()将数据随机分配给Reduce,这样可以使得每个Reduce处理的数据大体一致。对于4T的数据总共会起1099(默认最大值)的Reduces,修改的SQL如下:

hive> insert overwrite table test partition(dt)
> select * from iteblog_tmp
> DISTRIBUTE BY rand();
最终sql运行时间优化到1小时10分钟。

后来查看hdfs上文件时发现又部分分区下存在小文件的情况。

通过如下命令调整reduce个数:

set mapred.reduce.tasks= 600;---Reduce个数

最终sql执行时长为50分钟。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值