streaming mr

在以前的一篇关于python版MR实例的文章中,只是简单走了一下流程,这次主要是解决上次遗留的key,partition,sort的问题。以进一步理解hadoop streaming,也尝试mapper使用python而reducer使用bash的结合方式

1. 省略本地测试这个环节,可参考以前的那篇文章,HDFS上的测试数据位:
[root@hadoop Desktop]# hadoop fs -cat /usr/egencia/travler/travler.txt
/usr/hadoop/hadoop-1.2.1/libexec/../conf/hadoop-env.sh: line 59: export: `mapred.tasktracker.reduce.tasks.maximum=4': not a valid identifier
Warning: $HADOOP_HOME is deprecated.

air:343;hotel:45;train:54467;nation:china
air:367;hotel:456;train:5567;nation:china
air:356;hotel:4522;train:54367;car:454;nation:china
air:343;hotel:45;train:54467;nation:usa
air:367;hotel:456;train:5567;nation:usa
air:356;hotel:4522;train:54367;car:454;nation:usa
air:343;hotel:45;train:54467;nation:india
air:367;hotel:456;train:5567;nation:india
air:356;hotel:4522;train:54367;car:454;nation:india

2.假定需求为:
2.1 每个国家一个输出文件
2.2 输出文件格式为:
air:343:china
hotel:45:china
........

2.3 每个输出文件按照第一个字段排序后按照第二个字段排序

3 设计
key:第一和第三个字段
mapper输出为:air:343:china
partition:第三个字段
sort:第一和第二字段

4.mapper(python):
[root@hadoop Desktop]# cat tmapper.py
#!/usr/bin/python

import sys

line=sys.stdin.readline()
#print line[-1]
try:
    while line:
        line=line[:-1]
        #print line
        products=line.split(";")
        nations=products[-1].split(":")
        nation=nations[-1]
        prolen=len(products)
        for index,pro in enumerate(products):
            if index==(prolen-1):
                break
            else:
                subs=pro.split(":")
                print subs[0]+":"+subs[-1]+":"+nation
        line=sys.stdin.readline()
except :
    print "error"


5.reducer(bash):
/bin/cat

6.先不执行分区和排序:
[root@hadoop Desktop]# hadoop jar /usr/hadoop/hadoop-1.2.1/contrib/streaming/hadoop-streaming-1.2.1.jar \                                    > -D mapred.reduce.tasks=3 \
> -input /usr/egencia/travler \
> -output /usr/egencia/travler/out \
> -mapper tmapper.py \
> -reducer /bin/cat \
> -file tmapper.py

查看输出文件:
[root@hadoop Desktop]# hadoop fs -ls /usr/egencia/travler/out
/usr/hadoop/hadoop-1.2.1/libexec/../conf/hadoop-env.sh: line 59: export: `mapred.tasktracker.reduce.tasks.maximum=4': not a valid identifier
Warning: $HADOOP_HOME is deprecated.

Found 5 items
-rw-r--r--   1 root supergroup          0 2013-09-06 02:42 /usr/egencia/travler/out/_SUCCESS
drwxr-xr-x   - root supergroup          0 2013-09-06 02:42 /usr/egencia/travler/out/_logs
-rw-r--r--   1 root supergroup        160 2013-09-06 02:42 /usr/egencia/travler/out/part-00000
-rw-r--r--   1 root supergroup        189 2013-09-06 02:42 /usr/egencia/travler/out/part-00001
-rw-r--r--   1 root supergroup        132 2013-09-06 02:42 /usr/egencia/travler/out/part-00002
[root@hadoop Desktop]# hadoop fs -cat /usr/egencia/travler/out/part-00000  /usr/egencia/travler/out/part-00001 \
>  /usr/egencia/travler/out/part-00002
/usr/hadoop/hadoop-1.2.1/libexec/../conf/hadoop-env.sh: line 59: export: `mapred.tasktracker.reduce.tasks.maximum=4': not a valid identifier
Warning: $HADOOP_HOME is deprecated.

air:343:usa
air:367:usa
car:454:india
hotel:4522:china
hotel:4522:usa
hotel:456:india
hotel:45:usa
train:54367:china
train:54367:usa
train:5567:india
air:343:india
air:356:india
air:356:usa
air:367:india
car:454:china
car:454:usa
hotel:456:china
hotel:45:india
train:54467:india
train:54467:usa
train:5567:china
train:5567:usa
air:343:china
air:356:china
air:367:china
hotel:4522:india
hotel:456:usa
hotel:45:china
train:54367:india
train:54467:china

7. 删除输出目录后,
指定分割符号为:
指定第一和第三个字段为key
指定分区为第三个字段
重新执行
第一种执行:
 hadoop jar /usr/hadoop/hadoop-1.2.1/contrib/streaming/hadoop-streaming-1.2.1.jar -D mapred.reduce.tasks=3 -D stream.map.output.field.separator=: -D tream.num.map.output.key.fields=1  -input /usr/egencia/travler -output /usr/egencia/travler/out -mapper tmapper.py -reducer /bin/cat -file tmapper.py

结果
Warning: $HADOOP_HOME is deprecated.

hotel   45:china
hotel   456:china
hotel   4522:china
hotel   45:usa
hotel   456:usa
hotel   4522:usa

每个文件都是按照产品进行了partition

hadoop jar /usr/hadoop/hadoop-1.2.1/contrib/streaming/hadoop-streaming-1.2.1.jar \
-D mapred.reduce.tasks=3 \
-D stream.map.output.field.separator=: \
-D tream.num.map.output.key.fields=1 \
-D map.output.key.field.separator=: \
-D mapred.text.key.partitioner.options=-k3 \
-input /usr/egencia/travler \
-output /usr/egencia/travler/out \
-mapper tmapper.py \
-reducer /bin/cat -file tmapper.py \
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner

hadoop jar /usr/hadoop/hadoop-1.2.1/contrib/streaming/hadoop-streaming-1.2.1.jar \
-D stream.map.output.field.separator=: \
-D stream.num.map.output.key.fields=3 \
-D map.output.key.field.separator=: \
-D mapred.text.key.partitioner.options=-k2 \
-D mapred.reduce.tasks=2 \
-input /usr/egencia/travler \
-output /usr/egencia/travler/out \
-inputformat org.apache.hadoop.mapred.TextInputFormat \
-mapper tmapper.py \
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
-file tmapper.py \
-outputformat org.apache.hadoop.mapred.TextOutputFormat \
-reducer /bin/cat


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MapReduce是一种分布式计算模型,Python可以通过Hadoop Streaming实现MapReduce功能。以下是一个使用Python实现的简单MapReduce示例: 假设我们有一个包含数字的文本文件,我们想要计算每个数字出现的次数。 首先,我们需要编写一个map.py脚本来实现map函数的功能。map.py的代码如下所示: ``` #!/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)) ``` 这个脚本将输入的每一行文本拆分成单个数字,并将每个数字输出为键值对(数字,1)。 接下来,我们需要编写一个reduce.py脚本来实现reduce函数的功能。reduce.py的代码如下所示: ``` #!/usr/bin/env python import sys current_word = None current_count = 0 word = None 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: print('%s\t%s' % (current_word, current_count)) current_count = count current_word = word if current_word == word: print('%s\t%s' % (current_word, current_count)) ``` 这个脚本将接收到的键值对按键进行排序,并且累加相同键的值。最后输出每个数字出现的次数。 最后,我们可以通过Hadoop Streaming来运行MapReduce作业。假设我们的输入文件名为input.txt,输出文件名为output.txt,我们可以使用以下命令来运行: ``` hadoop jar /path/to/hadoop-streaming.jar \ -file /path/to/map.py -mapper /path/to/map.py \ -file /path/to/reduce.py -reducer /path/to/reduce.py \ -input /path/to/input.txt -output /path/to/output.txt ``` 这个命令将使用MapReduce对输入文件进行处理,并将结果输出到指定的输出文件中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值