Hive小文件问题

最近发现离线任务对一个增量Hive表查询越来越慢,推测是由小文件产生的

取HDFS查看确实存在480个小文件

于是合并小文件

insert into test select * from table distribute by floor (rand()*5)

这里采用distribute by进行小文件合并,通过rand()*5,保存从map端输出的文件最多输出到5个reducer,现在只剩下3个文件


小文件合并后同样的查询速度提升非常多。

因为此表格每天有数据进去,增量数据会单独生成一个小文件,日积月累生成大量小文件。小文件对Namenode内存造成压力,对map端文件合并也有很大压力


小文件产生原因

1.动态分区插入数据,会产生大量小文件

2.数据源本来就含有大量小文件

3.数据增量导入,如Sqoop数据导入,增量insert导入数据等

4.分桶表

5.可以修改的表,此种表有一个快照,随时间增加数据越来越大

小文件危害

1.给NameNode内存中fsImage合并造成压力

2.未开启小文件合并,每个文件一个MapTask,集群资源浪费

3.Map端设置小文件合并,单小文件 太多查询缓慢


小文件问题解决

1.Hive参数调节

Hive已经对小文件做了许多优化,只需修改配置文件即可


2.动态分区插入式,保证有静态分区,不要误判产生大量分区

创建分区表
hive (default)> create table dept_partition_dy(id int, name string) partitioned by (loc int) row format delimited fields terminated by '\t';
插入数据
set hive.exec.dynamic.partition.mode = nonstrict;hive (default)> insert into table dept_partition_dy partition(loc) select deptno, dname, loc from dept;

3.按照分区合并导入

如果原表有大量小文件,在导入目标表的时候也会产生大量小文件。如果有分区如dt、hour,可以使用 distribute by dt,hour,

保证每小时数据在一个reduce里面

4.定期合并数据

类似于增量导入数据,会存在小文件,需要进行一天或者一周的定时文件合并

5.覆盖原表数据

insert overwrite table test [partition] select * from table distribute by floor (rand()*5)

将test表中的数据查询出来,在overwrite覆盖表test,不必担心失败数据没有,这里面是有事务保证的。

若是分区表则加上partitiom,标识对分区进行overwrite

6.针对ORC存储的表

ORC格式的表可以使用

alter table test [partition(...)] concatenate

进行小文件合并,这种方法仅适用于ORC格式存储的表

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容