文章目录
一、介绍
1.1 streaming简介
- Streaming框架允许任何程序语言实现的程序在Hadoop MapReduce中使用,方便已有程序向Hadoop平台移植。
- Streaming的原理是用Java实现一个包装用户程序的MapReduce程序,该程序负责调用MapReduce Java接口获取key/value对输入,创建一个新的进程启动包装的用户程序,将数据通过管道传递给包装的用户程序处理,然后调用MapReduce Java接口将用户程序的输出切分成key/value对输出。
1.2 streaming优点
- 开发效率高,便于移植
按照标准输入输出编程就可以满足Hadoop要求,单机程序稍改动便能在集群上运行,便于测试。
测试代码 : cat input | mapper | sort | reducer > output - 程序运行效率高
对于CPU密集的计算,有些语言如C/C++比用JAVA编写的程序效率更高。 - 便于平台进行资源控制
Streaming框架中通过limi等方式可以灵活地限制应用程序使用的内存等资源。
1.3 streaming不足
- Hadoop Streaming默认只能处理文本数据,无法直接对二进制数据进行处理,如果要对二进制数据处理,可以将二进制的key和value进行base64的编码转化成文本。
- 两次数据拷贝和解析(分割),带来一定开销。
二、执行原理
三、具体参数
参数 | 解释 |
---|---|
-input <path> | 输入数据路径 |
-output <path> | 输出数据路径 |
-mapper <cmd|JavaClassName> | mapper可执行程序或Java类 |
-reducer <cmd|JavaClassName> | reducer可执行程序或Java类 |
-file <file> Optional | 分发本地文件 |
-cacheFile <file> Optional | 分发HDFS文件 |
-cacheArchive <file> | Optional 分发HDFS压缩文件 |
-numReduceTasks <num> Optional | reduce任务个数 |
-jobconf | -D NAME=VALUE Optional | 作业配置参数 |
-combiner <JavaClassName> Optional | Combiner Java类 |
-partitioner <JavaClassName> Optional | Partitioner Java类 |
各个参数的详细说明:
- -input
:指定作业输入,path可以是文件或者目录,可以使用*通配符,-input选项可以使用多次指定多个文件或目录作为输入。 - -output
:指定作业输出目录,path必须不存在,而且执行作业的用户必须有创建该目录的权限,-output只能使用一次。 - -mapper:指定mapper可执行程序或Java类,必须指定且唯一。
- -reducer:指定reducer可执行程序或Java类,可以省略(看需求)。
- -file:用于向计算节点分发本地文件。①map和reduce的执行文件 ②map和reduce要输入的 文件,如配置文件。
- -cacheFile:用于向计算机节点发HDFS文件(文件已经存在于HDFS上)
- -cacheArchive:用于向计算机节点发HDFS压缩文件(文件已经存在于HDFS上)
- -numReduceTasks:指定reducer的个数,如果设置-numReduceTasks 0或者-reducer NONE则没有reducer程序,mapper的输出直接作为整个作业的输出。
- -jobconf | -D NAME=VALUE:指定作业参数,NAME是参数名,VALUE是参数值,可以指定的参数参考hadoop-default.xml。注意:用-D作为参数时,必须在所有参数的最前面
下列是-jobconf | -D 一些用法(▲表示常用)
条件 | 作用 |
---|---|
▲mapred.job.name | 作业名 |
▲mapred.job.priority | 作业优先级 |
▲mapred.job.map.capacity | 最多同时运行map任务数 |
▲mapred.job.reduce.capacity | 最多同时运行reduce任务数 |
▲mapred.map.tasks | map任务个数 |
▲mapred.reduce.tasks | reduce任务个数 |
mapred.task.timeout | 任务没有响应(输入输出)的最大时间 |
mapred.compress.map.output | map的输出是否压缩 |
mapred.map.output.compression.codec | map的输出压缩方式 |
mapred.compress.reduce.output | reduce的输出是否压缩 |
mapred.output.compression.codec | reduce的输出压缩方式 |
四、实践
4.1 -file的应用
[root@master mr_file_broadcast]# cat map.py
import sys
def read_local_file_func(f):
word_set=set()
with open(f,'r') as word:
for line in word:
word_set.add(line.strip())
return word_set
def mapper_func(white_file):
word_set=read_local_file_func(white_file)
for line in sys.stdin:
ss=line.strip().split(' ')
for s in ss:
word=s.strip()
if word!=""and (word in word_set):
print "%s\t%s" % (s,1)
if __name__ == '__main__':
module=sys.modules[__name__]
func=getattr(module,sys.argv[1])
args=None
if len(sys.argv)>1:
args=sys.argv[2:]
func(*args)
[root@master mr_file_broadcast]# cat
import sys
def reducer_func():
current_word=None
count_pool=[]
sum=0
for line in sys.stdin:
word,value=line.strip().split()
if current_word==None:
current_word=word
if current_word!=word:
for count in count_pool:
sum+=count
print "%s\t%s" % (current_word,str(sum))
current_word=word
count_pool=[]
sum=0
count_pool.append(int(value))
for count in count_pool:
sum+=count
print "%s\t%s" % (current_word,str(sum))
if __name__ == '__main__':
module=sys.modules[__name__]
func=getattr(module,sys.argv[1])
args=None
if len(sys.argv)>1:
args=sys.argv[2:]
func(*args)
[badou&#