为什么带有python的hadoop mapReduce失败了,但是脚本在命令行上工作?

为什么带有python的hadoop mapReduce失败了,但是脚本在命令行上工作?,python,hadoop,mapreduce,cloudera-quickstart-vm,Python,Hadoop,Mapreduce,Cloudera Quickstart Vm,我正在尝试使用Cloudera 5.5.0实现一个简单的Hadoop map reduce示例 map&reduce步骤应该使用Python 2.6.6实现 问题: 如果脚本是在unix命令行上执行的,那么它们工作得非常好,并产生了预期的输出 cat join2*.txt |/join3_mapper.py | sort |/join3_reducer.py #!/usr/bin/env python import sys last_key = None

我正在尝试使用Cloudera 5.5.0实现一个简单的Hadoop map reduce示例 map&reduce步骤应该使用Python 2.6.6实现

问题:

  • 如果脚本是在unix命令行上执行的,那么它们工作得非常好,并产生了预期的输出
cat join2*.txt |/join3_mapper.py | sort |/join3_reducer.py

#!/usr/bin/env python
import sys

last_key      = None              #initialize these variables
running_total = 0
abcFound =False;
this_key      = None

# -----------------------------------
# Loop the file
#  --------------------------------
for input_line in sys.stdin:
    input_line = input_line.strip()

    # --------------------------------
    # Get Next Key value pair, splitting at tab
    # --------------------------------
    tuple2 = input_line.split("\t") 

    this_key = tuple2[0]    
    value = tuple2[1]
    if value.isdigit():
        value = int(value) 

    # ---------------------------------
    # Key Check part
    #    if this current key is same 
    #          as the last one Consolidate
    #    otherwise  Emit
    # ---------------------------------
    if last_key == this_key:     
        if value == 'ABC':  # filter for only ABC in TV shows
            abcFound=True;
        else:
            if isinstance(value, (int,long) ): 
                running_total += value   

    else:
        if last_key:         #if this key is different from last key, and the previous 
                             #   (ie last) key is not empy,
                             #   then output 
                             #   the previous <key running-count>
           if abcFound:
              print('%s\t%s' % (last_key, running_total) )
              abcFound=False;

        running_total = value    #reset values
        last_key = this_key

if last_key == this_key:
    print('%s\t%s' % (last_key, running_total) )
  • 但是将脚本作为hadoop任务执行非常失败
hadoop jar/usr/lib/hadoop-mapreduce/hadoop-streaming.jar-input/user/cloudera/inputv/join2_gen*.txt-output/user/cloudera/output_tv-mapper/home/cloudera/join3_mapper.py-reducer/home/cloudera/join3_reducer.py-numReduceTasks 1

16/01/06 12:32:32信息mapreduce。作业:任务Id:尝试\u 1452069211060\u 0026\u r\u000000\u 0,状态:失败
错误:java.lang.RuntimeException:PipeMapRed.waitOutputThreads():子进程失败,代码为1
位于org.apache.hadoop.streaming.PipeMapRed.waitOutputThreads(PipeMapRed.java:325)
位于org.apache.hadoop.streaming.PipeMapRed.mapRedFinished(PipeMapRed.java:538)
位于org.apache.hadoop.streaming.PipeReducer.close(PipeReducer.java:134)
位于org.apache.hadoop.io.IOUtils.cleanup(IOUtils.java:244)
位于org.apache.hadoop.mapred.ReduceTask.runOldReducer(ReduceTask.java:459)
位于org.apache.hadoop.mapred.ReduceTask.run(ReduceTask.java:392)
位于org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:163)
位于java.security.AccessController.doPrivileged(本机方法)
位于javax.security.auth.Subject.doAs(Subject.java:415)
位于org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1671)
位于org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:158)

  • 如果使用-numReduceTasks 0执行hadoop命令,则映射器可以工作, hadoop作业仅执行映射步骤,并成功结束,输出目录包含映射步骤的结果文件

  • 我想那减少步骤一定有问题吧

  • 色调中的stderr日志没有显示任何相关信息:
日志上传时间:星期三2016年1月6日12:33:10-0800 原木长度:222 log4j:WARN找不到记录器(org.apache.hadoop.ipc.Server)的appender。 log4j:警告请正确初始化log4j系统。 log4j:有关更多信息,请参阅警告

脚本代码: 第一个文件:join3_mapper.py

#!/usr/bin/env python

import sys

for line in sys.stdin:
   line       = line.strip()   #strip out carriage return
   tuple2  = line.split(",")   #split line, into key and value, returns a list

   if len(tuple2) == 2:
      key = tuple2[0]
      value = tuple2[1]
      if value == 'ABC':
         print('%s\t%s' % (key, value) )
      elif value.isdigit():
         print('%s\t%s' % (key, value) ) 
第二个文件:join3_reducer.py

#!/usr/bin/env python
import sys

last_key      = None              #initialize these variables
running_total = 0
abcFound =False;
this_key      = None

# -----------------------------------
# Loop the file
#  --------------------------------
for input_line in sys.stdin:
    input_line = input_line.strip()

    # --------------------------------
    # Get Next Key value pair, splitting at tab
    # --------------------------------
    tuple2 = input_line.split("\t") 

    this_key = tuple2[0]    
    value = tuple2[1]
    if value.isdigit():
        value = int(value) 

    # ---------------------------------
    # Key Check part
    #    if this current key is same 
    #          as the last one Consolidate
    #    otherwise  Emit
    # ---------------------------------
    if last_key == this_key:     
        if value == 'ABC':  # filter for only ABC in TV shows
            abcFound=True;
        else:
            if isinstance(value, (int,long) ): 
                running_total += value   

    else:
        if last_key:         #if this key is different from last key, and the previous 
                             #   (ie last) key is not empy,
                             #   then output 
                             #   the previous <key running-count>
           if abcFound:
              print('%s\t%s' % (last_key, running_total) )
              abcFound=False;

        running_total = value    #reset values
        last_key = this_key

if last_key == this_key:
    print('%s\t%s' % (last_key, running_total) )
#/usr/bin/env python
导入系统
last_key=None#初始化这些变量
总运行时间=0
abcFound=False;
此密钥=无
# -----------------------------------
#循环文件
#  --------------------------------
对于sys.stdin中的输入行:
input_line=input_line.strip()
# --------------------------------
#获取下一个键值对,在制表符处拆分
# --------------------------------
tuple2=输入线拆分(“\t”)
此_键=tuple2[0]
值=元组2[1]
如果值为.isdigit():
value=int(值)
# ---------------------------------
#钥匙检查部件
#如果此当前密钥相同
#随着最后一次合并
#否则发出
# ---------------------------------
如果最后一个\u键==此\u键:
如果值=='ABC':#仅筛选电视节目中的ABC
abcFound=True;
其他:
如果isinstance(值,(int,long)):
运行_总计+=值
其他:
如果最后一个键:#如果此键与最后一个键不同,则为上一个键
#(即最后一把)钥匙不是empy,
#然后输出
#前
如果ABC发现:
打印(“%s\t%s%”(最后一个密钥,运行总数))
abcFound=False;
运行_总计=值#重置值
最后一个密钥=此密钥
如果最后一个\u键==此\u键:
打印(“%s\t%s%”(最后一个密钥,运行总数))
我尝试了各种不同的方法将输入文件声明为hadoop命令,没有区别,没有成功


我做错了什么?非常感谢您的提示和想法,谢谢您

多么幸运的一拳,与之搏斗了几天,我知道我成功了:

自本地(unix)执行

cat join2_gen*.txt | ./join2_mapper.py | sort | ./join2_reducer.py
工作正常我想到使用1个合并输入文件,而不是提供的6个输入文件,因此:

cat join2_gen*.txt >> mergedinputFile.txt

hdfs dfs -put mergedInputFile.txt /user/cloudera/input
然后再次执行相同的hadoop命令,将输入定向到输入文件夹中的mergedInputFile-->完美结果,没有问题,没有异常工作完成

对我来说,它提出了一个问题:

  • 为什么它只处理一个合并的输入文件,而现在只提供较小的6个文件??(还不知道)

尝试将所有输入文本文件放在一个目录中,然后将该目录作为输入传递。这样,您就不必合并所有输入文件

难道不需要toolrunner才能从命令行运行jar文件吗?另外,jar文件不是用于Java程序的吗?我自己不是在执行jar文件,而是在执行hadoop命令并告诉hadoop执行声明的jar文件。库路径后面的其余部分是与hadoop-streaming.jar相关的参数,并且与执行的MapReduce操作相关。是的,jar文件是java程序我也有同样的问题!它在串行模式下工作得很好。