转个解决 MapredLocalTask的帖子
我的问题是目录没有其他用户读权限,所以报错
不知道是不是hive-0.12版增强了local mode的原因,在之前版本运行好好的Hive-QL在这个版本上错误频频,折磨一天多以后终于定位到原因,把在内部的总结在这再记录下,希望对遇到同样问题的筒子们有所帮助。
部分一 关于return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask
Hive升级到0.12版之后,若干原来在0.10上执行正常的SQL会在新版上报错误 “return code 1 from org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask”,查看hive执行日志,从中找到如下错误
1. Total MapReduce jobs = 1
2. java.io.IOException: Cannot run program "/data/opt/hadoop_cdh5/bin/hadoop" (in directory "/root"): error=13, 权限不够
3. 1041)
4. 617)
5. 450)
6. 253)
7. 151)
8. 65)
9. 1485)
10. 1263)
11. 1091)
12. 931)
13. 921)
14. 198)
15. 644)
16. 628)
17. 39)
18. 39)
19. 244)
20. 1145)
21. 615)
22. 744)
23. Caused by: java.io.IOException: error=13, 权限不够
24. at java.lang.UNIXProcess.forkAndExec(Native Method)
25. 135)
26. 130)
27. 1022)
28. 19
29. FAILED: Execution Error, return code 1
从上边错误及下边报错的类MapredLocalTask可以看出跟本地任务有关
hive从0.7版以后,为了提高小数据的计算速度,增加了本地模式,即将hdfs上的数据拉到hiveserver本地进行计算,可以通过以下几个参数对相关行为进行设置
hive.exec.mode.local.auto=false
hive.exec.mode.local.auto.input.files.max=4
hive.exec.mode.local.auto.inputbytes.max=134217728
其中第一个为不启用本地模式,第二个参数表示文件数小于4时使用本地模式,第三个参数表示文件大小小于128m时采用本地模式
默认为不启用本地模式;在启用的情况下,满足第二、三个条件中的任意一个都会使用本地模式。
在之前我们用过的0.8.1、0.10版上都未遇到过上述错误,怀疑是现在0.12版本的问题突然导致上述错误。任务是在root用户下通过crontab调用的,进入shell后先启动hiveserver,所以默认工作目录其实是/root;为了能正常读写hdfs上的文件,hiveserver在启动时切换到了hdfs用户,一旦遇到上述两种满足启用本地模式的情况,hdfs用户试图向当前工作目录/root拉取数据,必然没有权限从而导致以上错误。
理清问题所在就好办了,我们可以先创建一个目录,把用户、用户组授权给hdfs,进入shell后,先切换工作目录,然后再启动hiveserver即可。如hdfs的home目录/home/hdfs
然后在任务shell的公共配置文件conf/kettle.conf中增加一行切换目录脚本即可解决以上问题
cd /home/hdfs
部分二 关于return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask
类似上一篇中return code 1的问题,这个也是跟hive本地任务有关系。
从hive的日志中可以找到出错时本地日志文件,如下:
查看日志文件内容
1. 2014-07-10 11:50:37,606 INFO mr.ExecDriver (SessionState.java:printInfo(417)) - Execution log at: /tmp/hdfs/hdfs_20140710114949_ab4d1d02-0637-4abd-9e45-2a27c5d740d9.log
2. 2014-07-10 11:50:37,711 WARN conf.Configuration (Configuration.java:loadProperty(2358)) - file:/tmp/hdfs/hive_2014-07-10_11-49-37_877_2428431256361163465-1/-local-10009/jobconf
3. 2014-07-10 11:50:37,720 WARN conf.Configuration (Configuration.java:loadProperty(2358)) - file:/tmp/hdfs/hive_2014-07-10_11-49-37_877_2428431256361163465-1/-local-10009/jobconf
4. 2014-07-10 11:50:37,798 INFO log.PerfLogger (PerfLogger.java:PerfLogBegin(97)) - <PERFLOG method=deserializePlan from=org.apache.hadoop.hive.ql.exec.Utilities>
5. 2014-07-10 11:50:37,798 INFO exec.Utilities (Utilities.java:deserializePlan(732)) - Deserializing MapredLocalWork via kryo
6. 2014-07-10 11:50:38,043 INFO log.PerfLogger (PerfLogger.java:PerfLogEnd(124)) - </PERFLOG method=deserializePlan start=1404964237798 end=1404964238043 duration=245
7. 2014-07-10 11:50:38,050 INFO mr.MapredLocalTask (SessionState.java:printInfo(417)) - 2014-07-10 11:50:38
8. 2014-07-10 11:50:38,059 INFO mr.MapredLocalTask (MapredLocalTask.java:initializeOperators(389)) - fetchoperator for
9. 2014-07-10 11:50:38,198 INFO exec.TableScanOperator (Operator.java:initialize(338)) - Initializing Self 0
10. 2014-07-10 11:50:38,198 INFO exec.TableScanOperator (Operator.java:initializeChildren(403)) - Operator 0
11. 2014-07-10 11:50:38,199 INFO exec.TableScanOperator (Operator.java:initializeChildren(407)) - Initializing children of 0
12. 2014-07-10 11:50:38,199 INFO exec.SelectOperator (Operator.java:initialize(442)) - Initializing child 1
13. 2014-07-10 11:50:38,199 INFO exec.SelectOperator (Operator.java:initialize(338)) - Initializing Self 1
14. 2014-07-10 11:50:38,605 ERROR mr.MapredLocalTask (MapredLocalTask.java:executeFromChildJVM(324)) - Hive Runtime Error: Map local work failed
15. java.lang.RuntimeException: java.lang.ClassNotFoundException: com.renren.hive.date.GetWeekISO
16. 132)
17. 1474)
18. 1437)
19. 132)
20. 83)
21. 73)
22. 59)
23. 377)
24. 453)
25. 409)
26. 188)
27. 377)
28. 408)
29. 302)
30. 728)
31. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
32. 57)
33. 43)
34. 606)
35. 212)
36. Caused by: java.lang.ClassNotFoundException: com.renren.hive.date.GetWeekISO
37. 1.run(URLClassLoader.java:366)
38. 1.run(URLClassLoader.java:355)
39. at java.security.AccessController.doPrivileged(Native Method)
40. 354)
41. 425)
42. 358)
43. at java.lang.Class.forName0(Native Method)
44. 270)
45. 130)
由上可知,这次是找不到UDF的类(如遇到其他情况,需要具体问题具体分析),虽然在进入hive的时候通过add jar语句将自定义函数的jar包添加到hadoop集群,但在本地模式时确找不到了。定位到问题就好解决了:既然是local模式找不到udf jar包,说明在add jar步骤只是向当前job在hdfs上的工作目录下添加了,无视本地工作目录;那么我们就直接把udf的jar包copy到hive的lib目录下,测 试正常。
该问题在之前用过的hive 0.10、0.8.1中都未遇到过,初步猜测跟0.12版的bug有关,具体原因就需要花时间翻代码对照前后版本的变动了
从org.apache.hadoop.hive.ql.exec.mr.MapredLocalTask代码中看,还有return code 3的情况,现在幸运的尚未遇到,遇到后再补记录