一、hive常用参数
0.常用参数
--@Name: --@Description: --@Type:全量加载 --@Author:--- --@CreateDate: --@Target: --@SourceTable: --@ModifyBy: --@ModifyDate: --@ModifyDesc: --@Copyright --设置作业名 set mapred.job.name = hive_xxx(${statisdate}); --Map输入合并大小 set mapreduce.input.fileinputformat.split.maxsize=300000000; set mapreduce.input.fileinputformat.split.minsize=100000000; set mapreduce.input.fileinputformat.split.minsize.per.node=100000000; set mapreduce.input.fileinputformat.split.minsize.per.rack=100000000; set hive.input.format = org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; --设置reduce数目 set hive.exec.reducers.bytes.per.reducer= 300000000; set hive.exec.reducers.max=300; --输出合并 set hive.merge.mapfiles = true; set hive.merge.mapredfiles = true; set hive.merge.size.per.task = 128000000; set hive.merge.smallfiles.avgsize=16000000; --是否使用mapjoin set hive.auto.convert.join = false; --设置默认用户 use xxx_db;
1.任务名设置
set mapreduce.job.name=xxxx(${statis_date}) # 方便定位具体任务
2.输入合并参数设置
set mapreduce.input.fileinputformat.split.maxsize=300000000; set mapreduce.input.fileinputformat.split.minsize=100000000; set mapreduce.input.fileinputformat.split.minsize.per.node=100000000; set mapreduce.input.fileinputformat.split.minsize.per.rack=100000000; set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat; --不进行小文件合并
3.输出合并参数设置
set hive.merge.mapfiles = true #在Map-only的任务结束时合并小文件 set hive.merge.mapredfiles = true #在Map-Reduce的任务结束时合并小文件 set hive.merge.size.per.task = 256*1000*1000 #合并文件的大小 set hive.merge.smallfiles.avgsize=16000000 #当输出文件的平均大小小于该值时,启动一个独立的map-reduce任务进行文件merge
4.reduce设置
set hive.exec.reducers.bytes.per.reducer= 300000000; set hive.exec.reducers.max=300; set mapred.reduce.tasks=10; #固定reduce大小
5.mapjoin参数设置
set hive.auto.convert.join= false; -- 是否开启mapjoin set hive.auto.convert.join.noconditionaltask = true ; -- 是否将多个mj合并成一个 set hive.auto.convert.join.nonconditionaltask.size = 1000000; -- 多个mj合并后的大小(阈值)
6.map端聚合
set hive.map.aggr = true;
7.mapreduce的物理内存、虚拟内存
set mapreduce.map.memory.mb = 4096; set mapreduce.reduce.memory.mb = 4096; set mapreduce.map.java.opts=-Xmx3278m; set mapreduce.reduce.java.opts=-Xmx3278m; --------------------------------------------------- -- set mapreduce.map.memory.mb = 4096; -- set mapreduce.reduce.memory.mb = 4096; -- 此参数设计必须在允许范围内 -- yarn.scheduler.maximum-allocation-mb=8192; -- yarn.scheduler.minimum-allocation-mb=1024; --------------------------------------------------- -- 堆内存设置要小于物理内存,一般设置为80% -- set mapreduce.map.java.opts=-Xmx1638m; -- set mapreduce.reduce.java.opts=-Xmx3278m; --------------------------------------------------- -- Application application_1409135750325_48141 failed 2 times due to AM Container for -- appattempt_1409135750325_48141_000002 exited with exitCode: 143 due to: Container -- [pid=4733,containerID=container_1409135750325_48141_02_000001] is running beyond physical memory limits. -- Current usage: 2.0 GB of 2 GB physical memory used; 6.0 GB of 4.2 GB virtual memory used. Killing container. -- #虚拟内存打开:yarn.nodemanager.vmem-check-enabled=true -- 最大允许使用的虚拟内存=最大可使用的物理内存 * yarn.nodemanager.vmem-pmem-ratio=2.1 -- #物理内存检查打开:yarn.nodemanager.pmem-check-enabled=true -- 两者中有一个超过允许最大内存,此container容器均会被杀 ---------------------------------------------------
8.动态分区
set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; # 非严格模式
9. shuffle端内存溢出oom (BoundedByteArrayOutputStream)
set mapreduce.reduce.shuffle.memory.limit.percent=0.10;
10.map段谓词下推
set hive.optimize.ppd=true;
11.并行执行
set hive.exec.parallel=true; set hive.exec.parallel.thread.number=16; # 并行度
12.reduce申请资源时机
mapreduce.job.reduce.slowstart.completedmaps=0.05 控制当map任务执行到哪个比例的时候就可以开始为reduce task申请资源 mapreduce.job.reduce.slowstart.completedmaps这个参数如果设置的过低,那么reduce就会过早地申请资源,造成资源浪费; 如果这个参数设置的过高,比如为1,那么只有当map全部完成后,才为reduce申请资源,开始进行reduce操作,实际上是串行执行,不能采用并行方式充分利用资源。 如果map数量比较多,一般建议提前开始为reduce申请资源。
二、hive任务优化
1.分区裁剪
1.查询涉及分区表时,限制分区范围
2.使用to_unix_timestamp代替unix_timestamp(),避免全表扫描
2.列裁剪
只读取查询中需要用到的列,忽略其他不关心的列 Select * from table_test; Select field_1,field_2,… from table_test; Select * 跟select 所有字段是否一样?(网络IO,索引)
3.合理设置map、reduce个数
Map数: splitSize=Math.max(minSize, Math.min(maxSize, blockSize)) reduce数: reducers = Math.min(maxReducers, totalInputFileSize/bytesPerReducer)
# 根据任务运行效率,调整map reduce处理数据量大小
4.group by 优化
set hive.map.aggr=true; select id,count(1) from test group by id; set hive.groupby.skewindata = true; • 先不按GroupBy字段分发,随机分发做一次聚合 • 额外启动一轮job,拿前面聚合过的数据按GroupBy字段分发再算结果
5.join优化
大表跟小表之间join时,可打开mapjoin,将小表加载到内存中 set hive.mapjoin.smalltable.filesize 25M set hive.auto.convert.join = true; ps:不能只看文件大小,决定使用使用mapjoin,容易导致OOM(字段、过滤、去重后的记录数跟文件大小) --map端join把小表读入内存 set hive.exec.parallel=true; select /*+mapjoin(t2)*/ t1.vendor_cd, t2.vendor_cd from (select vendor_cd from tmp_tt ) t1 left outer join (select vendor_cd from tmp_tt limit 10 ) t2 on t1.vendor_cd=t2.vendor_cd limit 100; --控制map数,并且用mapjoin实现笛卡尔积 set mapred.reduce.tasks=10; set hive.input.format=org.apache.hadoop.hive.ql.io.HiveInputFormat; --不进行小文件合并 set hive.exec.parallel=true; select /*+mapjoin(t2)*/ t1.vendor_cd, t2.vendor_cd from (select vendor_cd from tmp_tt distribute by vendor_cd ) t1 left outer join (select vendor_cd from tmp_tt distribute by vendor_cd ) t2 limit 100;
6.数据倾斜
--特殊倾斜值的处理(null值很多的时候) set hive.exec.parallel=true; select t1.vendor_cd, t2.vendor_cd from (select vendor_cd from tmp_tt ) t1 left outer join (select vendor_cd from tmp_tt ) t2 on nvl(t1.vendor_cd,concat('hive_',rand()))=t2.vendor_cd limit 100;
--当心关联的类型是否一致,类型不一致可能会导致数据倾斜或者算出意想不到的结果 set hive.exec.parallel=true; select t1.vendor_cd, t2.vendor_cd from (select vendor_cd //int类型 from tmp_tt ) t1 left outer join (select vendor_cd //string类型 from tmp_tt ) t2 on cast(t1.vendor_cd as string)=t2.vendor_cd limit 100;