赞
踩
目录
1. 使用 hive 自带的 concatenate 命令,自动合并小文件
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 有多少个就输出多少个文件
也有很多简单任务没有reduce,只有map阶段,则
每执行一次 insert 时hive中至少产生一个文件,因为 insert 导入时至少会有一个MapTask。
首先对底层存储HDFS来说,HDFS本身就不适合存储大量小文件,小文件过多会导致namenode元数据特别大, 占用太多内存,严重影响HDFS的性能
对 hive 来说,在进行查询时,每个小文件都会当成一个块,启动一个Map任务来完成,而一个Map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的Map数量是受限的。
先执行一次insert ,插入两条数据
0: jdbc:hive2://hdp101:2181,hdp103:2181,hdp10> insert into table test1 values (1,'aa',67),(2,'bb',87);
0: jdbc:hive2://hdp101:2181,hdp103:2181,hdp10> alter table test1 concatenate;
设置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;
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 © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。