一、Hadoop streaming 详解
Hadoop streaming能够让Ruby、Python、PHP、和C++等非Java类语言编写的map或reduce程序在hadoop集群上运行,且map/reduce程序只要遵循从标准输入stdin,到标准输出stdout即可。
1.1 Hadoop流命令使用
参数 | 可选/必选 | 解释 |
-input | 必选 | 输入文件路径 |
-output | 必选 | 输出文件路径 |
-mapper | 必选 | 用户自己写的mapper程序,可以是可执行文件或者脚本 |
-reducer | 必选 | 用户自己写的reducer程序,可以是可执行文件或者脚本 |
-file | 可选 | 打包文件到提交的作业中,可以是mapper或者reducer要用的输入文件,如配置文件,字典等 |
-partitioner | 可选 | 用户自定义的partitioner程序 |
-combiner | 可选 | 用户自定义的combiner程序(必须用java实现) |
二、实验内容和要求
2.1 编程实现文件合并和去重操作
对于两个输入文件,即文件A和文件B,请编写Python程序,利用Hadoop Streaming工具,对两个文件进行合并,并剔除其中重复的内容,得到一个新的输出文件C。下面是输入文件和输出文件的一个样例供参考。
输入文件A的样例如下:
13722222222 c
13622222222 b
13722222222 b
13733333333 c
13622222222 c
输入文件B的样例如下:
13722222222 c
13522222222 b
13722222222 b
13733333333 b
13622222222 c
根据输入文件A和B合并得到的输出文件C的样例如下:
13722222222 c
13622222222 b
13722222222 b
13733333333 c
13622222222 c
13522222222 b
13733333333 b
1.首先在/home/hadoop/py下创建mapper.py,reducer.py
mapper.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
for line in sys.stdin:
line = line.strip()
words = line.split()
print '%s\t%s' % (words[0],words[1])
reducer.py
#!/usr/bin/python
#-*-coding:utf-8-*-
import sys
a=[]
b=[]
for line in sys.stdin:
line = line.strip()
num,name = line.split('\t', 1)
#print(num,name)
a.append((num,name))
for i in a:
if i not in b:
b.append(i)
for j in range(len(b)):
print(b[j][0]+'\t'+b[j][1])
2.在/home/hadoop/py下创建A.txt,B.txt并提交到hdfs
[hadoop@MASTER py]$ cat A.txt
13722222222 c
13622222222 b
13722222222 c
13733333333 c
13622222222 c
[hadoop@MASTER py]$ cat B.txt
13722222222 c
13522222222 b
13722222222 b
13733333333 b
13622222222 c
上传文件目录/hdfsinput/Score需要事先创建好
[hadoop@MASTER ~]$ hadoop fs -mkdir -p /hdfsinput/Score
上传至hdfs
[hadoop@MASTER py]$ hadoop fs -put {A,B}.txt /hdfsinput/Score
3.测试:
[hadoop@MASTER ~]$ hadoop jar hadoop-streaming-2.7.7.jar -input /hdfsinput/Score/* -output /hdfsoutput/Score/ -mapper py/mapper.py -reducer py/reducer.py -file py/mapper.py -file py/reducer.py
输出结果的目录 /hdfsoutput/Score/不用创建,会自动生成,只要指定目录就行
4.查看计算结果:
[hadoop@MASTER ~]$ hadoop fs -cat /hdfsoutput/Score/part-00000
13522222222 b
13622222222 c
13622222222 b
13722222222 c
13722222222 b
13733333333 b
13733333333 c
可通过浏览器访问(主机IP:50070)看是否生成相应文件
2.2 编程实现平均成绩的计算
请编写Python程序,利用Hadoop Streaming工具对输入文件中数据计算学生平均成绩。输入文件中的每行内容均为一个学生的姓名和他相应的成绩,如果有多门学科,则每门学科为一个文件。要求在输出中每行有两个间隔的数据,其中,第一个代表学生的姓名,第二个代表其平均成绩。下面是输入文件和输出文件的一个样例供参考。
样例输入1如下:
张三 80
李四 78
王五 92
样例输入2如下:
张三 97
李四 94
王五 88
样本输出如下:
张三 88
李四 86
王五 90
1.首先在/home/hadoop/py下创建mapper.py,reducer.py
mapper.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
for line in sys.stdin:
line = line.strip()
words = line.split()
print '%s\t%s' % (words[0],words[1])
reducer.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
count=0
i=0
sum=0
for line in sys.stdin:
line = line.strip()
name,score = line.split('\t', 1)
if i==0:
current_name=name
i=1
try:
score = int(score)
except ValueError:
continue
if current_name == name:
count += 1
sum +=score
else:
print '%s\t%s' % (current_name,sum/count)
current_name=name
sum=score
count=1
print '%s\t%s' % (current_name,sum/count)
2.赋予执行权限
[hadoop@MASTER py]$ chmod +x mapper.py
[hadoop@MASTER py]$ chmod +x reducer.py
3.创建三个文件
[hadoop@MASTER py]$ cat chinese.txt english.txt math.txt
张三 80
李四 78
王五 92
张三 97
李四 94
王五 88
张三 88.5
李四 86
王五 90
4.把上边三个文件上传到hdfs中的/input目录中
[hadoop@MASTER py]$ hadoop fs -put {chinese,math,english}.txt /input
5.测试:
[hadoop@MASTER ~]$ hadoop jar hadoop-streaming-2.7.7.jar -input /input/* -output /output/ -mapper py/mapper.py -reducer py/reducer.py -file py/mapper.py -file py/reducer.py
6.查看计算结果
[hadoop@MASTER py]$ hadoop fs -cat /output/part-00000
张三 88
李四 86
王五 90