Hive:Python UDF出现“关闭操作符时的Hive运行时错误”

4
我是一名Hadoop和Python方面的新手,目前遇到一些问题,希望能得到您的帮助...我有一个文件,大约150条记录,每条记录有10列,已经被加载到了一个Hive表(table1)中。第10列(我们称之为col10)是使用utf-8编码的,所以为了解码它,我编写了一个小的Python函数(命名为pyfile.py),如下所示: Python函数:
import sys
import urllib
for line in sys.stdin:
    line = line.strip()
    col10 = urllib.unquote(line).decode('utf8')
    print ''.join(col10.replace("+",' '))

我使用以下命令将文件添加到分布式缓存中:

我使用以下命令将文件添加到分布式缓存中:

add FILE folder1/pyfile.py;

现在,我正在使用Transform调用此Python函数来处理我的Hive表中的col10,如下所示:

Select Transform(col10)
USING 'python pyfile.py'
AS (col10)
From table1;

问题描述:

当对表的前100条记录进行调用时,一切运行良好,但调用101-150条记录时会出现以下错误:

2015-10-30 00:58:20,320 INFO [IPC Server handler 0 on 33716] org.apache.hadoop.mapred.TaskAttemptListenerImpl: Diagnostics report from attempt_1445826741287_0032_m_000000_0: Error: java.lang.RuntimeException: Hive Runtime Error while closing operators
    at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.close(ExecMapper.java:217)
    at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:61)
    at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:453)
    at org.apache.hadoop.mapred.MapTask.run(MapTask.java:343)
    at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:163)
    at java.security.AccessController.doPrivileged(Native Method)
    at javax.security.auth.Subject.doAs(Subject.java:415)
    at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1671)
    at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: [Error 20003]: An error occurred when trying to close the Operator running your custom script.
    at org.apache.hadoop.hive.ql.exec.ScriptOperator.close(ScriptOperator.java:557)
    at org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:610)
    at org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:610)
    at org.apache.hadoop.hive.ql.exec.Operator.close(Operator.java:610)
    at org.apache.hadoop.hive.ql.exec.mr.ExecMapper.close(ExecMapper.java:199)
    ... 8 more

我将101-150条记录复制到一个文本文件中,然后单独在它们上运行Python脚本,发现脚本可以正常运行。

请告诉我为什么它会出现错误,并提供解决方案。

1个回答

1
您看到的错误信息意味着Python正在抛出一些异常。在调试这种情况时,我使用UDF代码中以下模式的方法已经起到了作用(请参阅我的博客文章)。
import sys
import urllib

try:
   for line in sys.stdin:
       line = line.strip()
       col10 = urllib.unquote(line).decode('utf8')
       print ''.join(col10.replace("+",' '))

except:
   #In case of an exception, write the stack trace to stdout so that we
   #can see it in Hive, in the results of the UDF call.
   print sys.exc_info() 

感谢maxymoo的帮助。我尝试了你的建议并运行了脚本。任务成功了(虽然我觉得它应该在第8条记录就失败了),但当我查看结果时,只有7条记录。在第8条记录处,它显示:“6965、6968、'ordinal not in range(128)”。我单独对第8条记录运行了脚本,它正常工作,我在Google上搜索了这个错误,但没有找到帮助。有什么建议吗? - Gaurav
似乎解码出现了问题,也许尝试使用urllib.unquote(line.decode('utf8'))。此外,我认为您可能想使用urllib.unquote_plus - maxymoo
尝试注释掉你的代码一部分,直到你能够精确定位它失败的位置,并且可以打印出'line','line.decode('utf-8')'等内容以查看它是否符合你的预期。 - maxymoo
我已经尝试了所有方法,但都没有帮助。我相信如果Python脚本中有任何错误,当我单独在第8条记录上运行它时,它应该会失败... - Gaurav
有人可以帮忙吗? - Gaurav
4
如果有人感兴趣的话,问题已经通过修改打印命令得到解决:print u''.join(col10.replace("+",' ')).encode('utf-8')。 - Gaurav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接