【Hive】小文件过多解决方案

您所在的位置:网站首页 hive怎么查看表数据 【Hive】小文件过多解决方案

【Hive】小文件过多解决方案

2024-07-10 21:07| 来源: 网络整理| 查看: 265

目录

一、小文件产生原因

二、小文件过多产生的影响

三、怎么解决小文件过多

1. 使用 hive 自带的 concatenate 命令,自动合并小文件

2. 调整参数减少Map数量

3. 减少Reduce的数量

一、小文件产生原因

hive 中的小文件是向 hive 表中导入数据时产生,所以先看下向 hive 中导入数据的几种方式

1.直接向表中插入数据

​​insert into table test1 values (1,'aa',67),(2,'bb',87);

2.通过load方式加载数据

load data local inpath '/root/score.csv' overwrite into table test1 -- 导入文件 load data local inpath '/root/score' overwrite into table test1 -- 导入文件夹

使用 load 方式可以导入文件或文件夹,当导入一个文件时,hive表就有一个文件,当导入文件夹时,hive表的文件数量为文件夹下所有文件的数量

3.通过查询方式加载数据

insert overwrite table test1 select id,name,score from test2;

这种方式是生产环境中常用的,也是最容易产生小文件的方式

insert 导入数据时会启动 MR 任务,MR中 reduce 有多少个就输出多少个文件

文件数量=ReduceTask数量*分区数

也有很多简单任务没有reduce,只有map阶段,则

文件数量=MapTask数量*分区数

每执行一次 insert 时hive中至少产生一个文件,因为 insert 导入时至少会有一个MapTask。

二、小文件过多产生的影响

首先对底层存储HDFS来说,HDFS本身就不适合存储大量小文件,小文件过多会导致namenode元数据特别大, 占用太多内存,严重影响HDFS的性能

对 hive 来说,在进行查询时,每个小文件都会当成一个块,启动一个Map任务来完成,而一个Map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的Map数量是受限的。

三、怎么解决小文件过多 1. 使用 hive 自带的 concatenate 命令,自动合并小文件

先执行一次insert ,插入两条数据

0: jdbc:hive2://hdp101:2181,hdp103:2181,hdp10> insert into table test1 values (1,'aa',67),(2,'bb',87);  打印的日志

 HDFS 文件夹下形成的文件

执行 insert 三次,test1  表下面会有三个小文件

使用 concatenate 进行合并 0: jdbc:hive2://hdp101:2181,hdp103:2181,hdp10> alter table test1 concatenate;

2. 调整参数减少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 = 256*1000*1000; -- 256M # 当输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge set hive.merge.smallfiles.avgsize=16000000; -- 16M

启用压缩

# hive的查询结果输出是否进行压缩 set hive.exec.compress.output=true; # MapReduce Job的结果输出是否使用压缩 set mapreduce.output.fileoutputformat.compress=true; 3. 减少Reduce的数量

reduce 的个数决定了输出的文件的个数,所以可以调整 reduce 的个数控制 hive 表的文件数量,hive中的分区函数 distribute by 正好是控制MR中 partition 分区的,然后通过设置 reduce 的数量,结合分区函数让数据均衡的进入每个 reduce 即可。

#设置reduce的数量有两种方式,第一种是直接设置reduce个数 set mapreduce.job.reduces=10; #第二种是设置每个reduce的大小,Hive会根据数据总大小猜测确定一个reduce个数 set hive.exec.reducers.bytes.per.reducer=5120000000; -- 默认是1G,设置为5G

--------------------------- 感谢点赞!------------------------------- --------------------------- 感谢点赞!------------------------------- --------------------------- 感谢点赞!-------------------------------



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3