Hive小文件合并

来源:CSDN 作者:网友

Hive的后端存储是HDFS,它对大文件的处理是非常高效的,如果合理配置文件系统的块大小,NameNode可以支持很大的数据量。但是在数据仓库中,越是上层的表其汇总程度就越高,数据量也就越小。而且这些表通常会按日期进行分区,随着时间的推移,HDFS的文件数目就会逐渐增加。

小文件带来的问题

关于这个问题的阐述可以读一读Cloudera的这篇文章。简单来说,HDFS的文件元信息,包括位置、大小、分块信息等,都是保存在NameNode的内存中的。每个对象大约占用150个字节,因此一千万个文件及分块就会占用约3G的内存空间,一旦接近这个量级,NameNode的性能就会开始下降了。

此外,HDFS读写小文件时也会更加耗时,因为每次都需要从NameNode获取元信息,并与对应的DataNode建立连接。对于MapReduce程序来说,小文件还会增加Mapper的个数,每个脚本只处理很少的数据,浪费了大量的调度时间。当然,这个问题可以通过使用CombinedInputFile和JVM重用来解决。

Hive小文件产生的原因

前面已经提到,汇总后的数据量通常比源数据要少得多。而为了提升运算速度,我们会增加Reducer的数量,Hive本身也会做类似优化——Reducer数量等于源数据的量除以hive.exec.reducers.bytes.per.reducer所配置的量(默认1G)。Reducer数量的增加也即意味着结果文件的增加,从而产生小文件的问题。

解决小文件的问题可以从两个方向入手:

1. 输入合并。即在Map前合并小文件

2. 输出合并。即在输出结果的时候合并小文件

配置Map输入合并


-- 每个Map最大输入大小,决定合并后的文件数

set mapred.max.split.size=256000000;

-- 一个节点上split的至少的大小 ,决定了多个data node上的文件是否需要合并

set mapred.min.split.size.per.node=100000000;

-- 一个交换机下split的至少的大小,决定了多个交换机上的文件是否需要合并

set mapred.min.split.size.per.rack=100000000;

-- 执行Map前进行小文件合并

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; 

配置Hive结果合并

我们可以通过一些配置项来使Hive在执行结束后对结果文件进行合并:

hive.merge.mapfiles 在map-only job后合并文件,默认true

hive.merge.mapredfiles 在map-reduce job后合并文件,默认false

hive.merge.size.per.task 合并后每个文件的大小,默认256000000

hive.merge.smallfiles.avgsize 平均文件大小,是决定是否执行合并操作的阈值,默认16000000

Hive在对结果文件进行合并时会执行一个额外的map-only脚本,mapper的数量是文件总大小除以size.per.task参数所得的值,触发合并的条件是:

根据查询类型不同,相应的mapfiles/mapredfiles参数需要打开;

结果文件的平均大小需要大于avgsize参数的值。

示例:

-- map-red job,5个reducer,产生5个60K的文件。

create table dw_stage.zj_small as

select paid, count (*)

from dw_db.dw_soj_imp_dtl

where log_dt = '2014-04-14'

group by paid;

-- 执行额外的map-only job,一个mapper,产生一个300K的文件。

set hive.merge.mapredfiles= true;

create table dw_stage.zj_small as

select paid, count (*)

from dw_db.dw_soj_imp_dtl

where log_dt = '2014-04-14'

group by paid;

-- map-only job,45个mapper,产生45个25M左右的文件。

create table dw_stage.zj_small as

select *

from dw_db.dw_soj_imp_dtl

where log_dt = '2014-04-14'

and paid like '%baidu%' ;

-- 执行额外的map-only job,4个mapper,产生4个250M左右的文件。

set hive.merge.smallfiles.avgsize=100000000;

create table dw_stage.zj_small as

select *

from dw_db.dw_soj_imp_dtl

where log_dt = '2014-04-14'

and paid like '%baidu%' ;

压缩文件的处理

对于输出结果为压缩文件形式存储的情况,要解决小文件问题,如果在Map输入前合并,对输出的文件存储格式并没有限制。但是如果使用输出合并,则必须配合SequenceFile来存储,否则无法进行合并,以下是示例:

set mapred.output.compression. type=BLOCK;

set hive.exec.compress.output= true;

set mapred.output.compression.codec=org.apache.hadoop.io.compress.LzoCodec;

set hive.merge.smallfiles.avgsize=100000000;

drop table if exists dw_stage.zj_small;

create table dw_stage.zj_small

STORED AS SEQUENCEFILE

as select *

from dw_db.dw_soj_imp_dtl

where log_dt = '2014-04-14'

and paid like '%baidu%' ;

使用HAR归档文件

Hadoop的归档文件格式也是解决小文件问题的方式之一。而且Hive提供了原生支持:

set hive.archive.enabled= true;

set hive.archive.har.parentdir.settable= true;

set har.partfile.size=1099511627776;

ALTER TABLE srcpart ARCHIVE PARTITION(ds= '2008-04-08', hr= '12' );

ALTER TABLE srcpart UNARCHIVE PARTITION(ds= '2008-04-08', hr= '12' );

如果使用的不是分区表,则可创建成外部表,并使用har://协议来指定路径。


相关文档推荐

腾讯大数据基于StarRocks的向量检索探索.PDF

1737425434 赵裕隆 3.48MB 34页 积分6

腾讯云流式湖仓统一存储实践.PDF

1737423643 李哲 1.95MB 0页 积分4

B站一站式大数据集群管理平台.PDF

1737421412 刘明刚 1.37MB 30页 积分6

StarRocks在爱奇艺大数据场景的实践.PDF

1737365327 林豪 3.57MB 27页 积分5

现代化实时数据仓库SelectDB.PDF

1737364398 周飞 1.52MB 32页 积分5

AIGC数据存储技术研究报告.PDF

1737359276  1.22MB 29页 积分5

时间管理技能.PPTX

1736902056  18.8MB 56页 积分6

时间管理实践员工培训.PPTX

1736899089  43.82MB 30页 积分8

让时间变得高效.PPTX

1736759440  6.84MB 34页 积分6

相关文章推荐

大数据开发流程及规范

网络收集 CIO之家的朋友 

大数据技术名词解释

51CTO CIO之家的朋友 

大数据常见问题之数据倾斜

CSDN CIO之家的朋友 

项目经理的时间管理法则

简书 难忘的一天