基础设置
队列选择
yarn队列分配,选择合适的队列进行运行,避免都在同一个繁忙的队列中运行。
SET mapreduce.job.queuename=xx;
控制mapper&reducer数目
合理控制文件切分的各种参数,使Mapper和Reducer数目达到一个合适的值,可以加快处理速度。
// HiveInputFormat文件格式
# 文件分割最大大小
set mapreduce.input.fileinputformat.split.maxsize=536870912;
# 文件分割最小值
set mapreduce.input.fileinputformat.split.minsize=236870912;
# 块大小
set dfs.block.size=128M;
// CombineHiveInputFormat文件格式
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
//每个Map最大输入大小
set mapred.max.split.size=256000000;
//一个节点上split的至少的大小
set mapred.min.split.size.per.node=100000000;
//一个交换机下split的至少的大小
set mapred.min.split.size.per.rack=100000000;
-
减小Mapper数目:资源紧张,输入数据量大,切分出来的Mapper数目较大,由于申请container和释放都需要时间,加上资源紧张,不好申请到,所以尽可能减少Mapper数量。
-
增加Mapper数目:数据量不大,但是每条数据处理耗时大,按照自然切分会导致map数目少,从而使得运行慢,需要加大Mapper数目。
# Reduce 文件分割大小
set hive.exec.reducers.bytes.per.reducer=536870912;
set hive.exec.reducers.max=999;
# 强制设置个数
set mapred.reduce.tasks = 15
小文件合并
Hive的后端存储是HDFS,它对大文件的处理是非常高效的,如果合理配置文件系统的块大小,NameNode可以支持很大的数据量。但是在数据仓库中,越是上层的表其汇总程度就越高,数据量也就越小。而且这些表通常会按日期进行分区,随着时间的推移,HDFS的文件数目就会逐渐增加。HDFS的文件元信息,包括位置、大小、分块信息等,都是保存在NameNode的内存中的。每个对象大约占用150个字节,因此一千万个文件及分块就会占用约3G的内存空间,一旦接近这个量级,NameNode的性能就会开始下降了,此外,HDFS读写小文件时也会更加耗时,因为每次都需要从NameNode获取元信息,并与对应的DataNode建立连接。对于MapReduce程序来说,小文件还会增加Mapper的个数,每个脚本只处理很少的数据,浪费了大量的调度时间。当然,这个问题可以通过使用CombinedInputFile
和JVM重用
来解决。
- 输入合并。即在Map前合并小文件,
CombineFileInputFormat
会将许多小文件“打包”为一个切片,使得每一个Map Task可以处理更多的数据。更为关键的是CombineFileInputFormat
在决定将哪些小文件的数据块“打包”为一个切片时会充分考虑数据本地性(节点本地性、机器本地性)的特性,因此不会在运行时间和网络带宽方面来很大的开销,在处理大文件时CombineFileInputFormat
也有优势,原因在于它会将同一节点上的多个数据块形成一个切片,对Data-Local Map Tasks可能带来一定的优化。
// 输入时候文件合并
//执行Map前进行小文件合并
set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;
//每个Map最大输入大小
set mapred.max.split.size=256000000;
//一个节点上split的至少的大小
set mapred.min.split