我是Map Reduce编程的新手,我已经在python中编写了算法,我需要运行' n'在' n'上映射相同程序的实例(我的算法)数据集。由于我的代码是在python中,我使用hadoopstreaming代码。
Hadoopstreaming文档在此建议 - http://hadoop.apache.org/docs/r1.2.1/streaming.html#How+do+I+process+files%2C+one+per+map%3F,"生成包含输入文件的完整HDFS路径的文件。每个map任务都会得到一个文件名作为输入。"
因此,我创建了一个文本文件,其中包含每个数据集文件的路径。为了测试,我已经写了一个字数统计程序 - http://www.michael-noll.com/tutorials/writing-an-hadoop-mapreduce-program-in-python/。在我的map函数中,我在执行实际字数之前已经编写了下面的代码
for line in sys.stdin:
# obtain filename from file list
filename = line.rstrip('\n')
localfilename = ntpath.basename(filename)
os.environ("hadoop dfs -get"+line+ " " + localfilename)
Q1。所以我的理解是每一行都将作为我的map函数的一个分割给出,因此split的数量应该是我主文件中split或line的数量。我的主文件中有三个文件名,但我可以看到创建了两个分割。为什么会这样?
Q2。我的工作失败了,我不知道为什么,在哪里查看这些日志文件?
Q3。除此之外,我有另一个选项处理我的要求,将我的三个数据集放入一个文件并用一些特定的分隔符分隔,然后可以设置此conf.set(“textinputformat.record.delimiter”,“specific-delimiter” “),但问题是它必须在java中完成。此外,在许多论坛中,编写自定义记录阅读器来实现此目的。因为我不擅长java,我在python中编写我的实现,无论如何设置这个参数还是不用编写java代码呢?
Q4。 hadoop中是否有其他选项可供我处理我的要求?
hduser@master:~/code$ hadoop jar /usr/local/hadoop-2.2.0/share/hadoop/tools/lib/hadoop-streaming-2.2.0.jar -mapper "python $PWD/fileprocess.py" -reducer "python $PWD/reduce.py" -input final.txt -output output.txt
14/09/16 05:27:23 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
packageJobJar: [/home/hduser/tmp/hadoop-unjar4045267665479713934/] [] /tmp/streamjob4078572719514334736.jar tmpDir=null
14/09/16 05:27:26 INFO client.RMProxy: Connecting to ResourceManager at master/10.0.0.4:8032
14/09/16 05:27:26 INFO client.RMProxy: Connecting to ResourceManager at master/10.0.0.4:8032
14/09/16 05:27:31 INFO mapred.FileInputFormat: Total input paths to process : 1
14/09/16 05:27:31 INFO mapreduce.JobSubmitter: number of splits:2
14/09/16 05:27:31 INFO Configuration.deprecation: user.name is deprecated. Instead, use mapreduce.job.user.name
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.jar is deprecated. Instead, use mapreduce.job.jar
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.output.value.class is deprecated. Instead, use mapreduce.job.output.value.class
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.mapoutput.value.class is deprecated. Instead, use mapreduce.map.output.value.class
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.job.name is deprecated. Instead, use mapreduce.job.name
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.input.dir is deprecated. Instead, use mapreduce.input.fileinputformat.inputdir
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.output.dir is deprecated. Instead, use mapreduce.output.fileoutputformat.outputdir
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.map.tasks is deprecated. Instead, use mapreduce.job.maps
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.output.key.class is deprecated. Instead, use mapreduce.job.output.key.class
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.mapoutput.key.class is deprecated. Instead, use mapreduce.map.output.key.class
14/09/16 05:27:31 INFO Configuration.deprecation: mapred.working.dir is deprecated. Instead, use mapreduce.job.working.dir
14/09/16 05:27:34 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1410171456875_0012
14/09/16 05:27:34 INFO impl.YarnClientImpl: Submitted application application_1410171456875_0012 to ResourceManager at master/10.0.0.4:8032
14/09/16 05:27:35 INFO mapreduce.Job: The url to track the job: http://master:8088/proxy/application_1410171456875_0012/
14/09/16 05:27:35 INFO mapreduce.Job: Running job: job_1410171456875_0012
14/09/16 05:27:51 INFO mapreduce.Job: Job job_1410171456875_0012 running in uber mode : false
14/09/16 05:27:51 INFO mapreduce.Job: map 0% reduce 0%
14/09/16 05:28:11 INFO mapreduce.Job: Task Id : attempt_1410171456875_0012_m_000001_0, Status : FAILED
Error: java.lang.RuntimeException: PipeMapRed.waitOutputThreads(): subprocess failed with code 2
at org.apache.hadoop.streaming.PipeMapRed.waitOutputThreads(PipeMapRed.java:320)
at org.apache.hadoop.streaming.PipeMapRed.mapRedFinished(PipeMapRed.java:533)
at org.apache.hadoop.streaming.PipeMapper.close(PipeMapper.java:130)
at org.apache.hadoop.mapred.MapRunner.run(MapRunner.java:61)
at org.apache.hadoop.streaming.PipeMapRunner.run(PipeMapRunner.java:34)
at org.apache.hadoop.mapred.MapTask.runOldMapper(MapTask.java:429)
at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341)
at org.apache.hadoop.mapred.YarnChild$2.run(YarnChild.java:162)
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:1491)
at org.apache.hadoop.mapred.YarnChild.main(YarnChild.java:157)
答案 0 :(得分:2)
Q1: Hadoop会按照自己认为合适的方式拆分每个文件,并且无法保证哪些线路位于哪里。您需要将您的行放入单独的文件中,以确保它们由单独的映射器处理。
对于您的示例,如果您有三个文件名,而不是将它们全部放入单个/TEMP/files
文件中,则应在子文件夹中创建三个文件,每个文件都有一个文件名,然后将它们添加到您的作业中,如下所示: -input /TEMP/files/*
。这将为您提供您正在寻找的行为。
请注意,您无法获得数据的任何位置。获取第一个文件引用的映射器可能需要从另一个节点获取它。根据群集的大小,您可能更有可能必须转到正在处理的大多数文件的网络。
Q2:命令行输出只会告诉您java容器故障,而不是python的实际错误。为此,您应该转到职业跟踪页面:http://localhost:50030/jobtracker.jsp
从那里,您可以在失败的工作下找到您的工作。单击该页面上的失败任务,然后选择任务日志列中的一个选项。从那里你会看到你的python脚本的stderr输出。
你正在使用os.environ做一些奇怪的事情。您应该使用子进程来执行命令。例如:
from subprocess import call
call(["/usr/bin/hadoop", "dfs", "-get", line, localfilename])
问题3:我不确定这里的要求是什么。您是在谈论上面文件引用的实际文件,然后您将直接通过-get进入映射器?您正在手动处理它们,因此它们所处的格式并不重要,因为它们没有被传递到map / reduce。
问题4:看起来你有一些你想并行处理的文件,但你不需要使用map / reduce。你基本上只是想利用你有一堆cpu的hadoop集群这一事实。这很好并且可以工作,但你并没有真正使用hadoop来做除了将工作转移到奴隶以外的任何事情。