MR程序 优化参数
1、客户端显示以及job任务名和优先级
##打印表头
set hive.cli.print.header=true;
set hive.cli.print.row.to.vertical=true;
set hive.cli.print.row.to.vertical.num=1;
##显示当前数据库
set hive.cli.print.current.db=true;
##job任务名
set mapreduce.job.name=p_${v_date};
##job优先级
set mapred.job.priority=HIGH;
##设置job的队列名
set mapreduce.job.queuename;
##需要使用hive的正则表达式,需要设置hive的参数
过滤调不需要的列名
set hive.support.quoted.identifiers=none;
SELECT `(id|100name)?+.+` from st;
2、map与reduce内存调整
#一个MapTask可使用的资源上限。内存溢出了,原因是数据量太大,导致在map的阶段内存不足
set mapreduce.map.memory.mb=9000;
set mapreduce.map.java.opts=-Xmx4096m -XX:+UseConcMarkSweepGC;
#可能出现在reduce的阶段,reduce设置的内存通常比map端设置的要大
set mapreduce.reduce.memory.mb=9000;
set mapreduce.reduce.java.opts=-Xmx8196m;
#环形缓冲区大小,一般为1/3、1/2的map的java堆栈内存,减小spill溢写次数
set mapreduce.task.io.sort.mb=512
#map阶段 减少合并meger次数 默认10,如果文件数很多,增大减少合并次数
set io.sort.factor
3、shuffle阶段copy map阶段输出文件的内存设置
### shuffle ###
参数: mapred.reduce.shuffle.input.buffer.percent(default 0.7)
说明: 用来缓存shuffle数据的reduce task heap百分比
这个参数其实是一个百分比,意思是说,shuffle在reduce内存中的数据最多使用内存量为:0.7 × maxHeap of reduce task。
缓存的数据量超过了这个值,便开始将缓存数据写入磁盘。
这个调小,是将reduce端用来做数据缓存的内存减少。防止下载一个过大的map输出直接撑爆内存,导致任务失败。
参数:mapred.job.shuffle.merge.percent(default 0.66)
说明:缓存的内存中多少百分比后开始做merge操作
假设mapred.job.shuffle.input.buffer.percent为0.7,reduce task的max heapsize为1G,那么用来做下载数据缓存的内存就为大概700MB左右,这700M的内存,也不是要等到全部写满才会往磁盘刷的,而是当这700M中被使用到了一定的限度
(通常是一个百分比),就会开始往磁盘刷。
假设mapred.job.shuffle.merge.percent(default 0.66)为0.66,那么当下载过来的map的输出在缓存中达到 0.7 maxHeap 0.66这个值,缓存的数据就开始往磁盘中写。
这个调小是在上一个的基础上,进一步提前了将缓存的数据写入磁盘的时间
参数:mapreduce.reduce.shuffle.memory.limit.percent
单个shuffle任务能使用的内存限额,默认是0.25,即为 Shuffle内存 * 0.25。
低于此值可以输出到内存,否则输出到磁盘。
#每个Reduce去Map中取数据的并行数。默认值是5
set mapreduce.reduce.shuffle.parallelcopies;
###shuffle ###
4、动态分区参数设置
#动态分区 非严格模式
set hive.exec.dynamic.partition=true;
set hive.exec.dynamic.partition.mode=nonstrict;
set hive.exec.max.dynamic.partitions.pernode =1000;
#mr总共可创建的最大分区数:默认1000
set hive.exec.max.dynamic.partition.partitions
#当前节点可创建的最大分区数 默认100
set hive.exec.max.dynamic.partition.partitions.pernode
##是否开启自动分区。适用于动态分区数过多插入的优化,默认false,(动态分区列将进行全局排序)
set hive.optimize.sort.dynamic.partition=true
5、开启支持正则表达式
set hive.support.quoted.identifiers=none;
6、mapper输入文件合并的参数
每个Map最大输入大小
set mapred.max.split.size=256000000;
一个节点上split的至少的大小(这个值决定了多个DataNode上的文件是否需要合并)
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;
7、设置map输出和reduce输出进行合并的参数
设置 map输出和reduce输出进行合并的相关参数
hive.merge.mapfiles= true
设置reduce端输出进行合并,默认为false
hive.merge.mapredfiles= true
设置合并文件的大小,合并之后每个文件大小为256M
hive.merge.size.per.task= 256 *1000 * 1000
输出文件的平均大小小于该值时,启动一个独立的MapReduce任务进行文件merge
hive.merge.smallfiles.avgsize=16000000
8、map和reduce个数的参数设置
#强制设置reducer个数
set mapred.reduce.tasks
8.1设置reduce个数(一个reduce生成一个文件) 如果存在数据倾斜的情况,单纯修改reduce个数没有用
8.1.1、如果不指定reduce个数,hive会基于一下两个参数自动计算
(1)hive.exec.reducers.bytes.per.reducer
这是每个reduce处理的数据量,默认为1G=1000000000
(2)hive.exec.reducers.max(每个任务的最大reduce个数,默认1009)
reduce个数=min(参数2,map端输出数据总量/参数1)
8.1.2、设置每个reduce处理的数据量(例如1M)
参数:hive.exec.reducers.bytes.per.reducer=1000000;
reduce个数=map端输出数据总量/参数
8.1.3、直接设置reduce个数
set mapred.reduce.tasks=5;
8.1.4、在8.2,8.3中设置的参数在以下情况出现时会失效
(1)sql语句中没有group by的汇总
(2)使用了order by
(3)有笛卡尔积
(4)map端输出的数据量小于hive.exec.reducers.bytes.per.reducer参数值
8.2设置map个数
#强制设置map个数
set mapred.map.tasks
#这个两个参数联合起来用,主要是为了方便控制mapreduce的map数量。比如我设置为1073741824,就是为了让每个map处理1GB的文件。默认265M 一个块大小
set mapreduce.input.fileinputformat.split.maxsize
set mapreduce.input.fileinputformat.split.minsize
set mapreduce.input.fileinputformat.split.minsize.per.node=256000000;
set mapreduce.input.fileinputformat.split.minsize.per.rack=256000000;
map个数和来源表文件压缩格式有关,.gz格式的压缩文件无法切分,每个文件会生成一个map
只有这个参数打开,下面的3个参数才能生效
set hive.hadoop.supports.splittable.combineinputformat=true;
每个map负载
set mapred.max.split.size=16000000;
每个节点map的最小负载,这个值必须小于set mapred.max.split.size的值 (这个值决定了多个DataNode上的文件是否需要合并)
set mapred.min.split.size.per.node=100000000;
每个机架map的最小负载(这个值决定了该机架下的文件是否需要合并)
set mapred.min.split.size.per.rack=100000000;
9、join 统计聚合之类的sql,防止数据倾斜
set hive.optimize.skewjoin=true;
set hive.skewjoin.key=500000;
set hive.skewjoin.mapjoin.map.tasks=10000;
set hive.skewjoin.mapjoin.min.split=33554432;
map端聚合(Group By)
(1)是否在Map端进行聚合,默认为True
hive.map.aggr = true
(2)在Map端进行聚合操作的条目数目
hive.groupby.mapaggr.checkinterval = 100000
(3)有数据倾斜的时候进行负载均衡(默认是false)
hive.groupby.skewindata = true
当选项设定为 true,生成的查询计划会有两个MR Job。第一个MR Job中,Map的输出结果会随机分布到Reduce中,每个Reduce做部分聚合操作,并输出结果,这样处理的结果是相同的Group By Key有可能被分发到不同的Reduce中,从而达到负载均衡的目的;第二个MR Job再根据预处理的数据结果按照Group By Key分布到Reduce中(这个过程可以保证相同的Group By Key被分布到同一个Reduce中),最后完成最终的聚合操作
(4)hive.map.groupby.sorted=true 默认true
map端groupby 排序,不必要的可以关闭
10、采用压缩参数
# 10.1 开启map输出阶段压缩可以减少job中map和Reduce task间数据传输量。
set hive.exec.compress.intermediate=true;
set mapreduce.map.output.compress=true;
set mapreduce.map.output.compress.codec=org.apache.hadoop.io.compress.SnappyCodec;
# 10.2 开启Reduce输出阶段压缩
set hive.exec.compress.output=true;
set mapreduce.output.fileoutputformat.compress=true;
set mapreduce.output.fileoutputformat.compress.codec =org.apache.hadoop.io.compress.SnappyCodec;
set mapreduce.output.fileoutputformat.compress.type=BLOCK;
11、并行执行
#开启任务并行执行 默认false
set hive.exec.parallel=true;
#同一个sql允许并行任务的最大线程数
set hive.exec.parallel.thread.number=16;
#JVM重利用
16、开启JVM重用
set mapreduce.job.jvm.numtasks=10;
或者
set mapred.job.reuse.jvm.num.tasks=15;
JVM重利用可以是Job长时间保留slot,直到作业结束,这对于有较多任务和较多小文件的任务是非常有意义的,因为减少了JVM的启动和初始化时间,从而减少执行时间。当然这个值不能设置过大,因为有些作业会有reduce任务,如果reduce任务没有完成,则map任务占用的slot不能释放,其他作业可能就需要等待。
12、创建最大文件数
#创建的最大文件数 默认100000
set hive.exec.max.created.files;
13、本地模式
# Hive可以通过本地模式在单台机器上处理所有的任务。
# 对于小数据集,执行时间可以明显被缩短。
set hive.exec.mode.local.auto=true;
set hive.exec.mode.local.auto.inputbytes.max=50000000;
set hive.exec.mode.local.auto.input.files.max=10;
14、
yarn.scheduler.minimum-allocation-mb 给应用程序Container分配的最小内存,默认值:1024
yarn.scheduler.maximum-allocation-mb 给应用程序Container分配的最大内存,默认值:8192
yarn.scheduler.minimum-allocation-vcores 每个Container申请的最小CPU核数,默认值:1
yarn.scheduler.maximum-allocation-vcores 每个Container申请的最大CPU核数,默认值:32
yarn.nodemanager.resource.memory-mb 给Containers分配的最大物理内存,默认值:8192
15、容错性优化
mapreduce.map.maxattempts 每个Map Task最大重试次数,一旦重试参数超过该值,则认为Map Task运行失败,默认值:4。
mapreduce.reduce.maxattempts 每个Reduce Task最大重试次数,一旦重试参数超过该值,则认为Map Task运行失败,默认值:4。
mapreduce.task.timeout Task超时时间,经常需要设置的一个参数,该参数表达的意思为:如果一个Task在一定时间内没有任何进入,即不会读取新的数据,也没有输出数据,则认为该Task处于Block状态,可能是卡住了,也许永远会卡住,为了防止因为用户程序永远Block住不退出,则强制设置了一个该超时时间(单位毫秒),默认是600000。如果你的程序对每条输入数据的处理时间过长(比如会访问数据库,通过网络拉取数据等),建议将该参数调大,该参数过小常出现的错误提示是“AttemptID:attempt_14267829456721_123456_m_000224_0 Timed out after 300 secsContainer killed by the ApplicationMaster.”。
17、mapjoin
1)开启MapJoin参数设置:
(1)设置自动选择Mapjoin
set hive.auto.convert.join = true; 默认为true
(2)大表小表的阀值设置(默认25M一下认为是小表)注:高版本可能不起作用了:
set hive.mapjoin.smalltable.filesize=25000000;
(3)hive.auto.convert.join.noconditionaltask:默认值true,表示是否启用hive根据输入文件的大小,将普通的表连接转化为mapjoin。
(4)hive.auto.convert.join.noconditionaltask.size:默认值10000000(字节数)。如果输入文件的大小小于该参数设定的值,则将普通的表连接转化为Mapjoin。
博文hive调优:
ORC小文件合并:ORC官网参数:https://orc.apache.org/docs/hive-config.html
set hive.merge.mapredfiles=true;
set hive.merge.smallfiles.avgsize=1000000000;
set hive.merge.mapfiles=true;
set hive.merge.mapredfiles=true;
--在编写具有ORC文件格式的表时,启用hive.merge.mapfiles,hive.merge.mapredfiles或hive.merge.tezfiles时,启用此配置属性将对小型ORC文件执行条带级快速合并。请注意,启用此配置属性将不支持填充公差配置(hive.exec.orc.block.padding.tolerance)
set hive.merge.orcfile.stripe.level=true;
set hive.merge.size.per.task=256000000;
set hive.merge.smallfiles.avgsize=256000000;
set mapreduce.input.fileinputformat.split.maxsize=256000000;
set mapreduce.input.fileinputformat.split.minsize=256000000;
set mapreduce.input.fileinputformat.split.minsize.per.node=256000000;
set mapreduce.input.fileinputformat.split.minsize.per.rack=256000000;
-- orc切分策略
set hive.exec.orc.split.strategy=ETL
压缩格式 工具 算法 文件扩展名 是否可切分
DEFLATE 无 DEFLATE .deflate 否
Gzip gzip DEFLATE .gz 否
bzip2 bzip2 bzip2 .bz2 是
LZO lzop LZO .lzo 否
LZ4 无 LZ4 .lz4 否
Snappy 无 Snappy .snappy 否