Hadoop Streaming - 无法找到文件错误

时间:2010-12-02 20:56:52

标签: python streaming hadoop mapreduce

我正在尝试运行hadoop-streaming python作业。

bin/hadoop jar contrib/streaming/hadoop-0.20.1-streaming.jar 
-D stream.non.zero.exit.is.failure=true 
-input /ixml 
-output /oxml 
-mapper scripts/mapper.py 
-file scripts/mapper.py 
-inputreader "StreamXmlRecordReader,begin=channel,end=/channel" 
-jobconf mapred.reduce.tasks=0 

我确保mapper.py具有所有权限。它错误地说

Caused by: java.io.IOException: Cannot run program "mapper.py":     
error=2, No such file or directory
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:460)
    at org.apache.hadoop.streaming.PipeMapRed.configure(PipeMapRed.java:214)
... 19 more
Caused by: java.io.IOException: error=2, No such file or directory
    at java.lang.UNIXProcess.forkAndExec(Native Method)
    at java.lang.UNIXProcess.(UNIXProcess.java:53)
    at java.lang.ProcessImpl.start(ProcessImpl.java:91)
    at java.lang.ProcessBuilder.start(ProcessBuilder.java:453)

我尝试将mapper.py复制到hdfs并提供相同的hdfs://localhost/mapper.py链接,这也不起作用!关于如何修复这个bug的任何想法?。

8 个答案:

答案 0 :(得分:7)

查看HadoopStreaming wiki page上的示例,您似乎应该更改

-mapper scripts/mapper.py 
-file scripts/mapper.py 

-mapper mapper.py 
-file scripts/mapper.py 

因为“已发送的文件将转到工作目录”。您可能还需要直接指定python解释器:

-mapper /path/to/python mapper.py 
-file scripts/mapper.py 

答案 1 :(得分:3)

你的问题很可能是奴隶上没有python可执行文件(TaskTracker正在运行)。 Java将给出相同的错误消息。

在任何地方安装它。你可以使用shebang取消你的文件:

#!/usr/bin/python -O
rest
of
the
code

确保shebang之后的路径与TaskTrackers上安装python的路径相同。

答案 2 :(得分:2)

另一个鬼鬼祟祟的事情可能导致这种情况。如果脚本上的行结尾是DOS风格的,那么你的第一行(" shebang line")可能看起来像肉眼:

#!/usr/bin/python

...my code here...

但是当它尝试执行你的脚本时,它的字节对内核来说是这样的:

% od -a myScript.py
0000000   #   !   /   u   s   r   /   b   i   n   /   p   y   t   h   o
0000020   n  cr  nl  cr  nl   .   .   .   m   y  sp   c   o   d   e  sp
0000040   h   e   r   e   .   .   .  cr  nl

它正在寻找一个名为"/usr/bin/python\r"的可执行文件,它无法找到,因此它会以"No such file or directory"而死。

今天这就是我,再次,所以我不得不把它写在SO的某个地方。

答案 3 :(得分:1)

我在尝试运行流式python作业的CDH4 Hadoop集群上遇到了完全相同的问题。诀窍是在mapper / reducer文件中添加第一行:

import sys
sys.path.append('.')

这将使python看起来在当前工作目录中,然后它应该能够运行,同时确保你的shebang是正确的。

答案 4 :(得分:1)

使用python代码运行map reduce时遇到了同样的问题。 解决方案是:我们必须在mapper和reducer前面指定“-file”。

这是命令:

hadoop jar /opt/cloudera/parcels/CDH-5.12.2-1.cdh5.12.2.p0.4/lib/hadoop-mapreduce/hadoop-streaming-2.6.0-cdh5.12.2.jar **-file /home/mapper.py** -mapper /home/mapper.py   **-file /home/reducer.py** -reducer /home/reducer.py  -input /system/mainstream/tmp/file.txt -output /system/mainstream/tmp/output

答案 5 :(得分:0)

你的mapper.py是否具有执行权限?如果没有,那么你需要它。

chmod a+x scripts/mapper.py

Hadoop在写入/读取到std之前分叉并运行脚本,因此您需要赋予它执行权限才能运行。

答案 6 :(得分:0)

当我的mapper返回null或空字符串时,我刚收到同样的错误。所以我不得不检查一下这个值:

try:
    # Skip over any errors

    word = words[18].strip()

        if (len(word) == 0):
            word = "UKNOWN"

    print '%s\t%s' % (word, 1)

except Value:
    pass

答案 7 :(得分:0)

找不到文件错误有时并不意味着"找不到文件"而是表示"无法执行此脚本"。

知道这个我解决了这样的问题,当你在流媒体上遇到问题(没有java)时,我建议你按照这个检查表:

  1. 脚本是否运行?不要开始使用口译员,即 python myScript.py使其成为./myScript.py启动时的可执行文件,这就是流媒体将调用您的脚本的方式。
  2. 使用-verbose查看将要部署到容器中的jar内容,有时这会有所帮助。
  3. 容器内部脚本是符号链接而不是真实文件。
  4. 使用-file移动的文件不在文件夹中。 -mapper folder/script.py-reducer folder/script.py被视为script.py
  5. 在作业完成后,容器及其中的任何内容都会被删除,如果你想看到容器中发生的事情,请将其移入HDFS,IE:用.sh脚本替换映射器或reducer,以完成工作。< / LI>

    这份清单给了我很多帮助,我希望对你也有用。

    以下是带有模糊错误消息的经典日志。

    确实如此,它无法运行程序。

    Caused by: java.io.IOException: Cannot run program "/hadoop/yarn/local/usercache/root/appcache/application_1475243242823_0007/container_1475243242823_0007_01_000004/./reducer.py": 
    error=2, No such file or directory
    

    谎言的原因。

        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1047)
        at org.apache.hadoop.streaming.PipeMapRed.configure(PipeMapRed.java:209)
        ... 15 more
    

    阅读本文:

    Caused by: java.io.IOException: error=2, No such file or directory
    

    这是谎言,如果-verbose将其显示在包装清单中,则文件确实存在。

        at java.lang.UNIXProcess.forkAndExec(Native Method)
        at java.lang.UNIXProcess.<init>(UNIXProcess.java:187)
        at java.lang.ProcessImpl.start(ProcessImpl.java:130)
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1028)