hive处理小文件(进行map、reduce、压缩、归档优化解决)

背景

Hive query将运算好的数据写回hdfs(比如insert into语句),有时候会产生大量的小文件,如果不采用CombineHiveInputFormat就对这些小文件进行操作的话会产生大量的map task,耗费大量集群资源,而且小文件过多会对namenode造成很大压力。所以Hive在正常job执行完之后,会起一个conditional task,来判断是否需要合并小文件,如果满足要求就会另外启动一个map-only job 或者mapred job来完成合并

 

一、    控制hive任务中的map数: 

1.    通常情况下,作业会通过input的目录产生一个或者多个map任务。 

主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小(目前为128M, 可在hive中通过set dfs.block.size;命令查看到,该参数不能自定义修改);

2.    举例:假设input目录下有1个文件a,大小为780M,那么hadoop会将该文件a分隔成7个块(6个128m的块和1个12m的块),从而产生7个map数。假设input目录下有3个文件a,b,c,大小分别为10m,20m,130m,那么hadoop会分隔成4个块10m,20m,128m,2m),从而产生4个map数。即,如果文件大于块大小(128m),那么会拆分,如果小于块大小,则把该文件当成一个块。

3.    map数越多越好?否定的。如果一个任务有很多小文件(远远小于块大小128m),则每个小文件也会被当做一个块,用一个map任务来完成,而一个map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的map数是受限的。

4.    是不是保证每个map处理接近128m的文件块,就可以了?也不一定。比如有一个127m的文件,正常会用一个map去完成,但这个文件只有一个或者两个小字段,却有几千万的记录,如果map处理的逻辑比较复杂,用一个map任务去做,肯定也比较耗时。

解决:减少map数

    假设一个SQL任务:select brand,("hour") time_type,("2018-12-04") times,("05") as hours,("201812") as months,("20181204") as days,count(distinct(openId)) brandCount from log_db.commodlog where create_time like "2018-12-04 05%" and openId !='' group by brand SORT BY brand ASC;

    该任务的inputdir  /user/hive/warehouse/log_db/commodlog/month=201812/day=20181204

    共有194个文件,其中很多是远远小于128m的小文件,总大小9G,正常执行会用194个map任务。

   Map总共消耗的计算资源: SLOTS_MILLIS_MAPS= 623,020

 

通过以下方法来在map执行前合并小文件,减少map数:

启动压缩

set hive.exec.compress.output=true;

set mapreduce.output.fileoutputformat.compress=true; 
set mapreduce.input.fileinputformat.split.maxsize=1073741824;

set mapreduce.input.fileinputformat.split.minsize=1;

set mapreduce.input.fileinputformat.split.minsize.per.node=536870912;

set mapred
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值