4

在一个 Ubuntu 虚拟机上,我按照 Michael Noll 的教程设置了一个单节点集群,这是我编写 Hadoop 程序的起点。

另外,作为参考,this .

我的程序是 Python 并使用 Hadoop Streaming。

我编写了一个简单的向量乘法程序,其中mapper.py接受输入文件v1v2,每个文件都包含表单中的向量12,33,10并返回乘积。然后reducer.py返回产品的总和,即:

映射器map(mult,v1,v2)

减速机sum(p1,p2,p3,...,pn)

映射器.py:

import sys

def mult(x,y):      
    return int(x)*int(y)

# Input comes from STDIN (standard input).

inputvec = tuple()

for i in sys.stdin:
    i = i.strip()

    inputvec += (tuple(i.split(",")),)

v1 = inputvec[0]
v2 = inputvec[1]

results = map(mult, v1, v2)

# Simply printing the results variable would print the tuple. This
# would be fine except that the STDIN of reduce.py takes all the 
# output as input, including brackets, which can be problematic

# Cleaning the output ready to be input for the Reduce step:

for o in results:
    print ' %s' % o,

减速器.py:

import sys

result = int()

for a in sys.stdin:

    a = a.strip()
    a = a.split()

for r in range(len(a)):
    result += int(a[r])

print result

in子目录中,我有v1contains5,12,20v2contains 14,11,3

在本地测试,事情按预期工作:

hduser@ubuntu:~/VectMult$ cat in/* | python ./mapper.py
 70  132  60

hduser@ubuntu:~/VectMult$ cat in/* | python ./mapper.py | sort
 70  132  60

hduser@ubuntu:~/VectMult$ cat in/* | python ./mapper.py | sort | python ./reducer.py
262

当我在 Hadoop 中运行它时,它似乎成功了,并且没有抛出任何异常:

hduser@ubuntu:/usr/local/hadoop$ bin/hadoop jar contrib/streaming/hadoop-*streaming*.jar -mapper python /home/hduser/VectMult3/mapper.py -reducer python /home/hduser/VectMult3/reducer.py -input /home/hduser/VectMult3/in -output /home/hduser/VectMult3/out4
Warning: $HADOOP_HOME is deprecated.

packageJobJar: [/app/hadoop/tmp/hadoop-unjar2168776605822419867/] [] /tmp/streamjob6920304075078514767.jar tmpDir=null
12/11/18 21:20:09 INFO util.NativeCodeLoader: Loaded the native-hadoop library
12/11/18 21:20:09 WARN snappy.LoadSnappy: Snappy native library not loaded
12/11/18 21:20:09 INFO mapred.FileInputFormat: Total input paths to process : 2
12/11/18 21:20:09 INFO streaming.StreamJob: getLocalDirs(): [/app/hadoop/tmp/mapred/local]
12/11/18 21:20:09 INFO streaming.StreamJob: Running job: job_201211181903_0009
12/11/18 21:20:09 INFO streaming.StreamJob: To kill this job, run:
12/11/18 21:20:09 INFO streaming.StreamJob: /usr/local/hadoop/libexec/../bin/hadoop job  -Dmapred.job.tracker=localhost:54311 -kill job_201211181903_0009
12/11/18 21:20:09 INFO streaming.StreamJob: Tracking URL: http://localhost:50030/jobdetails.jsp?jobid=job_201211181903_0009
12/11/18 21:20:10 INFO streaming.StreamJob:  map 0%  reduce 0%
12/11/18 21:20:24 INFO streaming.StreamJob:  map 67%  reduce 0%
12/11/18 21:20:33 INFO streaming.StreamJob:  map 100%  reduce 0%
12/11/18 21:20:36 INFO streaming.StreamJob:  map 100%  reduce 22%
12/11/18 21:20:45 INFO streaming.StreamJob:  map 100%  reduce 100%
12/11/18 21:20:51 INFO streaming.StreamJob: Job complete: job_201211181903_0009
12/11/18 21:20:51 INFO streaming.StreamJob: Output: /home/hduser/VectMult3/out4

hduser@ubuntu:/usr/local/hadoop$ bin/hadoop dfs -cat /home/hduser/VectMult3/out4/part-00000
Warning: $HADOOP_HOME is deprecated.

hduser@ubuntu:/usr/local/hadoop$ bin/hadoop dfs -ls /home/hduser/VectMult3/out4/
Warning: $HADOOP_HOME is deprecated.

Found 3 items
-rw-r--r--   1 hduser supergroup          0 2012-11-18 22:05 /home/hduser/VectMult3/out4/_SUCCESS
drwxr-xr-x   - hduser supergroup          0 2012-11-18 22:05 /home/hduser/VectMult3/out4/_logs
-rw-r--r--   1 hduser supergroup          0 2012-11-18 22:05 /home/hduser/VectMult3/out4/part-00000

但是当我检查输出时,我发现的只是一个 0 字节的空文件。

我无法弄清楚出了什么问题。任何人都可以帮忙吗?


编辑:回复@DiJuMx

解决此问题的一种方法是从 map 输出到临时文件,然后在 reduce 中使用临时文件。

不确定 Hadoop 是否允许这样做?希望有更了解的人可以纠正我。

在尝试此操作之前,请尝试编写一个更简单的版本,该版本只是直接传递数据而不进行处理。

我认为这是一个好主意,只是为了检查数据是否正确流过。我为此使用了以下内容:

mapper.py 和 reducer.py 都
导入 sys

for i in sys.stdin:
    print i,

出来的应该就是进去的。仍然输出一个空文件。

或者,如果输入为空白,则在 reduce 中编辑现有代码以将(错误)消息输出到输出文件

映射器.py

import sys

for i in sys.stdin:
    print "mapped",

print "mapper",

减速器.py

import sys

for i in sys.stdin:
    print "reduced",

print "reducer",  

如果收到输入,它应该最终输出reduced。无论哪种方式,它至少应该输出reducer. 实际输出仍然是一个空文件。

4

6 回答 6

0

我没有任何使用hadoop(或python)的经验,但是,我注意到你正在指定输出去,/home/hduser/VectMult3/out4但期望它在/home/hduser/VectMult3/out/part-00000.

您是否检查过该out4文件是否存在以及它的内容是什么?

于 2012-11-19T16:00:35.140 回答
0

您是否尝试过替换python mapper.py"python mapper.py"?我想映射器运行python而不是python mapper.py. 它可以解释你的空输出。此外,您的文件 mapper.py 不应位于 HDFS 上,而应位于本地某处。然后,使用命令行中的选项将其发送到作业 jar 文件 ( doc ) :-file <path_to_local_file>

/bin/hadoop jar contrib/streaming/hadoop-*streaming*.jar -mapper "python mapper.py" -file <path_to_your_local_mapper.py> -reducer "python reducer.py" -file <path_to_your_local_reducer.py> -input /home/hduser/VectMult3/in -output <output_dir_name>
于 2013-11-22T15:04:44.600 回答
0

我知道这个问题已经很老了,但我仍然想帮忙。我看到在您的 reducer.py 和 mapper.py 示例中,您只是输出一个值。我相信(我刚开始使用 Hadoop,但到目前为止这是我的经验)它需要一个由选项卡分隔的键值对。

例如,您的映射器的输出可能与此类似:
print "%s\t%s" % (str(random.randint(0,100000)), "mapped")

我不确定,但减速器可能可以输出任何东西。如果这仍然不起作用,请按照此博客http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/上的说明创建一个测试用例我的环境,所以希望它会为你做同样的事情。如果此示例不起作用,则很可能是您的 Hadoop 设置存在问题。

于 2013-04-03T15:09:09.290 回答
0

遇到过与此类似的问题,并发现确保以下行位于我的 Python 脚本的顶部已修复它:

#!/usr/bin/python

也许试一试,看看它是否有帮助?

ps 此外,仅查看我们的 Python 映射器和化简器,我们在行尾使用没有注释的 print 语句。

于 2013-11-25T14:08:29.623 回答
0

假设您的代码完全正确(如您的问题的第一部分所示,我将假设如此),问题可以缩小到您正在工作的环境。在这种情况下,我会说这是因为输出来自映射器的不是通过管道传输到减速器(就像您手动运行命令时一样)

解决此问题的一种方法是从 map 输出到临时文件,然后在 reduce 中使用临时文件。

在尝试此操作之前,请尝试编写一个更简单的版本,该版本只是直接传递数据而不进行处理。如果您仍然没有任何结果,请尝试临时文件。

或者,如果输入为空白,则在 reduce 中编辑现有代码以将(错误)消息输出到输出文件

于 2012-11-20T22:52:49.653 回答
0

我有同样的问题。mapper.py和reducer.py工作正常,但 Hadoop 流返回空文件,没有任何错误!

我通过使用 Hadoop Streaming 代码解决了这个问题,如下所示:(注意我用于 -mapper 和 -reducer 的格式!)

hadoop jar /usr/lib/hadoop-0.20-mapreduce/contrib/streaming/hadoop-*streaming*.jar -file /home/training/Desktop/mapper.py -mapper 'python mapper.py' -file /home/training/Desktop/reducer.py -reducer 'python reducer.py' -input /user/training/sales.csv -output /user/training/output18

我希望这对其他有同样问题的人有所帮助。

于 2015-07-11T02:04:53.267 回答