背景:任务topic#report_hw_user_stat#v1凌晨5点高峰期消耗vcore90000+ 执行时间600+s
调试:下午3点 较空闲时段
尝试1:多个union all
针对多个union all的优化,可以增加并行,通过set hive.exec.parallel默认是false, set hive.exec.parallel.thread.number 发现默认是8个,遂增加下面两个设置:
set hive.exec.parallel=true;
set hive.exec.parallel.thread.number=16;
结果:没有任何改进
before
*********************TASK RESOURCE INFO*********************
* applicationIds:['application_1537022799650_6260441'] *
* vcoreSecondsSum:9770 *
* memorySecondsSum:15075148 *
* mapCntSum:23 *
* reduceCntSum:3403 *
* containerCntSum:3426 *
* numFilesSum:1 *
* numRowsSum:6258 *
* totalSizeSum:193047 *
* rawDataSizeSum:186789 *
* hiveExecuteTime:84 *
************************************************************
after
*********************TASK RESOURCE INFO*********************
* applicationIds:['application_1537022799650_6260429'] *
* vcoreSecondsSum:9853 *
* memorySecondsSum:15194030 *
* mapCntSum:23 *
* reduceCntSum:3403 *
* containerCntSum:3426 *
* numFilesSum:1 *
* numRowsSum:6258 *
* totalSizeSum:193155 *
* rawDataSizeSum:186897 *
* hiveExecuteTime:85 *
************************************************************
尝试2:重设reducer个数
发现任务执行过程中,mapper 30个,reducer 有200个 (脚本中set mapred.reduce.tasks=200是从模板copy过来的,没有注意到,所有一直保留着)。感觉不太合理,基于mapper30个,先设置reducer20个试试。
before --200
*********************TASK RESOURCE INFO*********************
* applicationIds:['application_1537022799650_6292835'] *
* vcoreSecondsSum:10287 *
* memorySecondsSum:15911316 *
* mapCntSum:23 *
* reduceCntSum:3403 *
* containerCntSum:3426 *
* numFilesSum:1 *
* numRowsSum:6003 *
* totalSizeSum:185726 *
* rawDataSizeSum:179723 *
* hiveExecuteTime:130 *
************************************************************
after --20
*********************TASK RESOURCE INFO*********************
* applicationIds:['application_1537022799650_6292899'] *
* vcoreSecondsSum:2441 *
* memorySecondsSum:3729604 *
* mapCntSum:23 *
* reduceCntSum:343 *
* containerCntSum:366 *
* numFilesSum:1 *
* numRowsSum:6003 *
* totalSizeSum:185523 *
* rawDataSizeSum:179520 *
* hiveExecuteTime:80 *
************************************************************
数字喜人,效果明显,vcore消耗减少80%,执行时间减少40%,基本上100s以内的任务我们就算是优化成功了。
但是这里其实还有个问题,如何找到最优的reduce个数?根据以下公式可以大概估计:
num_Reduce_tasks = min[${hive.exec.reducers.max}, (${input.size} / ${ hive.exec.reducers.bytes.per.reducer})]
set hive.exec.reducers.bytes.per.reducer ------> 600M
explain 可以粗略估计input.size
我这里没有估计input.size,而是直接注释掉set mapred.reduce.tasks=200,默认执行-1,让hive自己计算需要多少个reduce,发现是31个,跟mapper差不多。执行结果如下,虽然时间差不多,但是vcore消耗减少更多,其它指标也有改善。
-- -1
*********************TASK RESOURCE INFO*********************
* applicationIds:['application_1537022799650_6292943'] *
* vcoreSecondsSum:734 *
* memorySecondsSum:1097340 *
* mapCntSum:23 *
* reduceCntSum:37 *
* containerCntSum:60 *
* numFilesSum:1 *
* numRowsSum:6003 *
* totalSizeSum:185651 *
* rawDataSizeSum:179648 *
* hiveExecuteTime:82 *
************************************************************
总结:
reduce的个数并不是越多越好
这个任务的逻辑有点复杂,hive启动了3个job来执行,说明代码逻辑本身还算合理,每个job启动要花时间,那80秒里代码的执行时间是更少,结果挺好的啦。
后面还可以尝试修改hive.exec.reducers.bytes.per.reducer,当前是600M,可以设置为300M,1G,1.5G,比较一下执行效果,进一步优化。