合并MapReduce作业的输出文件

时间:2013-12-14 08:21:10

标签: python hadoop mapreduce hadoop-streaming elastic-map-reduce

我在Python中编写了一个Mapper和Reducer,并使用Hadoop Streaming在Amazon的Elastic MapReduce(EMR)上成功执行了它。

最终结果文件夹包含三个不同文件part-00000,part-00001和part-00002的输出。但我需要输出作为一个单独的文件。我有办法做到吗?

这是我的Mapper代码:

#!/usr/bin/env python

import sys

for line in sys.stdin:
    line = line.strip()
    words = line.split()
    for word in words:
        print '%s\t%s' % (word, 1)

这是我的Reducer代码

#!/usr/bin/env python

from operator import itemgetter
import sys

current_word = None
current_count = 0
word = None
max_count=0

for line in sys.stdin:
    line = line.strip()
    word, count = line.split('\t', 1)

    try:
        count = int(count)
    except ValueError:
        continue

if current_word == word:
    current_count += count
else:
    if current_word:
        # write result to STDOUT
            if current_word[0] != '@':
                print '%s\t%d' % (current_word, current_count)
                if count > max_count:
                    max_count = count
    current_count = count
    current_word = word

if current_word == word:
    print '%s\t%s' % (current_word, current_count)

我需要将其输出作为单个文件。

4 个答案:

答案 0 :(得分:1)

一种非常简单的方法(假设Linux / UNIX系统):

$ cat part-00000 part-00001 part-00002 > output

答案 1 :(得分:0)

对小型数据集/处理使用single reduce或在作业的输出文件中使用getmerge选项。

答案 2 :(得分:0)

我对上述问题的解决方案是执行以下hdfs命令:

hadoop fs -getmerge /hdfs/path local_file

其中 / hdfs / path 是包含作业输出的所有部分(部分 - *****)的路径。 hadoop fs的-getmerge选项将所有作业输出合并到我们本地文件系统上的单个文件中。

答案 3 :(得分:0)

我最近遇到了同样的问题,实际上组合器应该完成这个任务,但我无法以某种方式实现。我做了什么;

  1. 第1步:mapper1.py reducer1.py

    输入:s3://../data/

    输出s3://..../small_output/

  2. 第2步:mapper2.py reducer2.py

    输入s3://../data/

    输出:s3://.... / output2 /

  3. 第3步:mapper3.py reducer3.py

    输入:s3://../output2/

    输出:s3://..../final_output /

  4. 我假设我们需要在步骤3中将step1的输出作为单个文件。

    在mapper2.py的顶部,有这段代码;

    if not os.path.isfile('/tmp/s3_sync_flag'):
        os.system('touch /tmp/s3_sync_flag')
        [download files to /tmp/output/]
        os.system('cat /tmp/output/part* > /tmp/output/all')
    

    if block,检查多个映射器执行。