Hadnoop权威指南 第2章 关于MapReduce 一个Python版本的小例子

一个基于Hadoop Streaming + Python的MapReduce例子

参见《Hadoop权威指南(第3版)》第二章

准备工作:

Hadoop2.7.2版本安装

python环境安装

数据准备:这里用的是NCDC的1901 1902两年的数据(其他的数据大家可以FTP下载下来)

实验目的:

通过Hadoop Streaming + Python统计每年最高气温

背景知识介绍:

Hadoop Streaming使用UNIX标准流作为Hadoop和应用程序之间的接口,因此任何语言都可以通过标准的输入/输出写MapReduce程序。后面会在程序的注释中说明数据是如何在Map和Reduce任务中流动的。


1. 上传数据到hdfs

我们将1901和1902两个文件上传到HDFS的/ncdc目录下

如果没有该目录,首先创建:

hdfs dfs -mkdir /ncdc

上传1901 1902两个文件到hdfs的/ncdc

hdfs dfs -put 1901 1902 /ncdc


2. 编写map和reduce程序

注意,map函数的输入就是数据文件,map函数从标准输入中获取数据,因此一般按行处理数据。以NCDC的数据为例子,每一行的格式如下:

0029029070999991901010106004+64333+023450FM-12+000599999V0202701N015919999999N0000001N9-00781+99999102001ADDGF108991999999999999999999

其中,第15到第19个字符表示年份,第87到第92个字符表示温度。

因此,map程序如下:

输入:NCDC数据
输出:年份+气温

#!/usr/bin/env python

import sys

for line in sys.stdin:
    year, temp = line[15:19], line[87:92]
    if temp != '+9999':
        print('%s\t%s' % (year, temp))
注意:

(1)头部必须添加,否则Hadoop不知道用什么去执行任务

<span style="font-family:Microsoft YaHei;">#!/usr/bin/env python</span>
(2)temp != '+9999'

此行对非法处理做过滤

(3)最后一行的输出就是reduce的输入,key和value之间用\t分割,由此可知,reduce的输入也是标准输入,中间的过程由hadoop控制


reduce程序将会获取同一个年份中的最高温度。

输入:年份+气温
输出:年份+最高气温

#!/usr/bin/env python

import sys

current_year=None
current_temp=-sys.maxint

for line in sys.stdin:
    year, temp = line.split()
    temp=int(temp)
    if year == current_year:
        if current_temp < temp:
            current_temp = temp
    else:
        if current_year:
            print("%s\t%s" % (current_year, current_temp))
        current_year=year
        current_temp=temp
if current_year:
    print("%s\t%s" % (current_year, current_temp))
代码有点多,我们一步一步分析:

(1)首先需要说明的是,reduce的输入是map的输出,而且输出已经被MapReduce框架根据键值做了排序,因此reduce的输入是按年份排序的 年份+气温。

(2)我们需要自己找到两个不同键值的交汇点,然后做相应的处理,因此我们使用了current_year和current_temp作为当前正在处理的年份和最高气温,如果下一条数据的年份year与current_year相同,证明还是同一个年份,这个时候需要判断该数据的温度temp是否大于current_temp,如果大于则current_temp=temp。如果year与current_year不同,证明到了下一个年份,这个时候就要输出当前的年份和最高温度current_year和current_temp,这里请大家再次注意,因为reduce的输入是按键值排序的,因此保证了此处的输出就是当前年份的最高温度。同时,要把current_year设置为year,将current_temp设置为temp

(3)注意最后两行代码,因为最后一个年份不会再出现year!=current_year的情况,因此需要最后两行,来把最后一个年份的最高温度输出出来,第一次看代码的时候有点晕,注意一下


3. 执行

(1)清理上次执行的结果(假定结果放在了/output/ncdc目录下)
hdfs dfs -rm -r /output/ncdc

(2)执行

hadoop jar hadoop/hadoop-2.7.3/share/hadoop/tools/lib/hadoop-streaming-2.7.3.jar 
-files python/ncdc/mapper.py,python/ncdc/reducer.py 
-input /ncdc/ 
-output /output/ncdc 
-mapper mapper.py 
-reducer reducer.py
注意参数-files,之前版本参数为-file,一次指定一个文件,现在改为了-files,指定多个需要发布到mapreduce执行环境的文件,不同文件之间用,分割。

-mapper 指定map处理程序,这里直接写文件名称即可

-reducer 指定reduce处理程序,这里直接写文件名称即可


(3)查看执行结果
hdfs dfs -cat /output/ncdc/part-00000


结果如下:

1901    317
1902    244


4. 权威指南中提到了可以考虑使用Dumbo框架作为Streaming的替代方案。给一篇参考文献:

http://www.oschina.net/translate/a-guide-to-python-frameworks-for-hadoop

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值