首页 > 代码库 > hive任务卡在个别reduce的问题分析
hive任务卡在个别reduce的问题分析
最近微博有一个任务需要使用日曝光表做统计,发现这个任务很容易在stage1卡在reduce100%阶段不动,发邮件过来让帮找一下问题或者优化一下,和同事一起分析了一下原因,以下是分析过程:
1、分析hql
add file get_recept_mid.sh; add file get_last_expo_mid.sh; add file get_real_recept.py; insert overwrite directory '/user/liangjun/hive-liangjun/' select transform(t2.uid,t7.mid,t2.expo_mid) using 'python get_real_recept.py' as uid,real_recept from ( select transform(t6.*) using 'sh get_recept_mid.sh' as uid,mid from ( select t3.fans_uid,t4.mid from ( select fans_uid,uid from mds_user_fanslist where dt=20140926 ) t3 join ( select transform(t5.*) using 'sh get_recept_mid.sh' as uid,mid from ( select uid,mid from mds_bhv_pubblog where dt=20140926 distribute by uid sort by uid ) t5 ) t4 on t3.uid=t4.uid distribute by t3.fans_uid sort by t3.fans_uid ) t6 ) t7 join ( select transform(t1.*) using 'sh get_recept_mid.sh' as uid,expo_mid from ( select t8.* from ( select transform(ods_tblog_expo.uid,ods_tblog_expo.mid_list) using 'sh get_last_expo_mid.sh' as uid,mid from ods_tblog_expo where dt=20140926 and interface_id in ('1','5') ) t8 distribute by t8.uid sort by t8.uid ) t1 ) t2 on t7.uid=t2.uid;
该hql有个特点:使用了多个脚本,包括python、shell
2、看是否有报错信息:
没有发现报错,但是卡在selectoperator处:
2014-09-29 10:22:23,162 INFO ExecReducer: ExecReducer: processing 10000000 rows: used memory = 110701640 2014-09-29 10:22:23,162 INFO org.apache.hadoop.hive.ql.exec.ExtractOperator: 2 forwarding 10000000 rows 2014-09-29 10:22:23,162 INFO org.apache.hadoop.hive.ql.exec.SelectOperator: 3 forwarding 10000000 rows
3、看是否有数据倾斜问题
查看了已经运行完成的reduce和卡住的reduce的counter信息,几个重要指标(FILE_BYTES_READ、FILE_BYTES_WRITTEN、HDFS_BYTES_WRITTEN)都差不多,不存在数据倾斜问题,但是FILE_BYTES_READ一直在动,而HDFS_BYTES_WRITTEN一直没反应。
4、查看了一下卡住的reduce任务java进程使用内存和cpu的情况
根据50030监控页面,找到卡住reduce任务运行所在的节点,根据任务id找到对应的进程id,分别通过jstat -gcutil ${pid} 1000,和top -p ${pid}查看内存和cpu使用情况,发现内存使用很少,cou使用也很低,排除是java进程内存不够和cpu使用过高问题的原因。
5、查看stage1 reduce阶段的执行计划:
Reduce Operator Tree: Extract Select Operator expressions: expr: _col0 type: string expr: _col1 type: string outputColumnNames: _col0, _col1 Transform Operator command: sh get_recept_mid.sh output info: input format: org.apache.hadoop.mapred.TextInputFormat output format: org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat File Output Operator compressed: false GlobalTableId: 0 table: input format: org.apache.hadoop.mapred.SequenceFileInputFormat output format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormat
从执行计划上面看出,stage1的reduce阶段使用了get_recept_mid.sh脚本,该脚本内容如下:
awk -F"\t" 'BEGIN{last=""}{ if(last!=$1&&last!=""){ print last"\t"mids mids="" } if(mids==""){ mids=$2 }else{ mids=mids","$2 } last=$1 }END{ print last"\t"mids }' /dev/stdin是一个awk,按理说awk还是很高效的。
既然使用了awk,在运行的时候肯定会起一个进程,我们来查看一下awk进程的内存和cpu使用情况,登陆到运行卡住recue任务的节点,执行top命令,发现确实有一个awk的进程,top -p ${pid},如下图所示:
发现awk实际使用的内存为13M,而且cpu使用达到100.3%,从这两个信息来看应该awk的问题导致reduce被卡住了,以下是找到的awk相关资料:
“awk有两种工作方式:交互方式及非交互方式。交互方式即输入数据由用户通过键盘输入,此时awk使用行缓冲区,每接收到一行输入数据立即输出。非交互方式的输入数据通过文件或管道输入,此时只有输入缓冲区满了才会输出,对于一些实时性的应用这种方式会带来困扰“
既然找到了问题的原因就好办了,解决办法将缓冲区的数据刷出去,修改后的脚本内容:
awk -F"\t" 'BEGIN{last=""}{ fflush("") if(last!=$1&&last!=""){ print last"\t"mids mids="" } if(mids==""){ mids=$2 }else{ mids=mids","$2 } last=$1 }END{ print last"\t"mids }' /dev/stdin从新提交job,发现很快运行完成,reduce被卡住问题解决。
参考:
http://hi.baidu.com/lyugb/item/3351d6100d7e7dfc756a8499
同事博客地址:http://dj1211.com/
hive任务卡在个别reduce的问题分析