hadoop stream 参数详解

原文地址:Hadoop streaming 作者:tivoli_chen

1 hadoop streaming

Hadoop streaming是和hadoop一起发布的实用程序。它允许用户创建和执行使用任何程序或者脚本编写的map或者reduce的mapreducejobs。譬如,

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input myInputDirs

-output myOutputDir

-mapper /bin/cat

-reducer /bin/wc


2hadoop straming工作方式

在上面的例子中,mapper和reducer都是可执行程序,mapper的输入是读取stdin,reducer的输出是输出到stdout。Hadoopstreaming可以创建mapreduce任务,提交任务到正确的cluster,监控任务的执行过程直到任务完成。

当mapper定义为可执行程序时,每个mapper task初始化都会独立启动该进程。Mappertask运行时,将输入的文件转换成行来处理,然后传入到stdin;同时,将输出处理为key-value,作为mapper的输出;默认情况下,每行数据第一个tab前面的数据是key,剩下的作为value。如果某行数据中没有tab,则将整行数据作为key,value值为null。然而,这些也可以自定义处理。

当reducer定义为可执行程序时,每个reducer task初始化都会独立启动该进程。Reducertask运行时,将输入的key-value数据转换成行数据,作为reducer的输入。同时,reducer收集行数据,将行数据转换成key-value形式输出。默认情况下,每行数据第一个tab前面的数据是key,剩下的作为value。然而,这些也可以自定义处理。

这是mapreduce框架和hadoop streaming之间的基本通信协议。

用户也可以定义java类作为mapper和reducer,例如,

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input myInputDirs

-output myOutputDir

-mapper org.apache.hadoop.mapred.lib.IdentityMapper

-reducer /bin/wc

用户可以定义stream.non.zero.exit.is.failure的值为true或者false来表示streaming任务是成功还是失败退出。

3Job提交设置file选项

用户可以定义任何程序作为mapper或者reducer。这些可执行程序不需要预先存放在集群的机器上。如果不能,可以通过-file选项来设置程序,提交给job。例如,

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input myInputDirs

-output myOutputDir

-mapper myPythonScript.py

-reducer /bin/wc

-file myPythonScript.py

该例子将python可执行程序作为mapper。选项-filemyPythonScript.py导致python脚本作为job提交的一部分被传送到集群的机器上。除了可执行程序文件,用户也可以打包一些其他的可能被mapper或者reducer使用的文件。例如,

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input myInputDirs

-output myOutputDir

-mapper myPythonScript.py

-reducer /bin/wc

-file myPythonScript.py

-file myDictionary.txt

4streaming选项和用法

4.1只有mapper的job

有时候,用户仅仅需要通过mapper函数对输入数据进行处理。要做到这些,可以设置mapred.reduce.tasks=0。这样,mapreduce框架就不会创建reducetask。并且,mapper的输出就是job的最终输出。为了支持向下兼容,hadoop streaming也支持选项-reduceNONE,等价于-D mapred.reduce.tasks=0。

4.2定义jobs的其他选项

作为一个正常的mapreduce job,用户可以定义hadoop streaming job的其他选项,

-inputformat JavaClassName

-outputformat JavaClassName

-partitioner JavaClassName

-combiner JavaClassName

设置input format的类应该返回text类的key-value键值对。如果没有设置inputformat类,默认的是TextInputFormat。TextInputFormat返回LongWritable类的keys,它并不是输入数据的一部分,keys可能被舍弃;只有values被传送到streamingmapper中。设置output format的类应该是text类的key-value键值对。如果没有定义outputformat类,默认的是TextOutputFormat。

4.3 hadoop streaming中的大文件和文件档案

-files 和–archives选项允许用户设置task的文件和文件档案。参数是已经在hdfs上的文件和文件档案的URI。这些文件和文件档案在job中缓存。用户可以从fs.default.name配置变量中获取host和fs_port的值。例如,-files选项,

-files hdfs://host:fs_port/user/testfile.txt#testlink

在这个例子中,url中#后面的部分是当前工作任务路径的符号链接。因此,这些任务拥有指向本地文件的符号链接。多个输入可以作如下设置,

-files hdfs://host:fs_port/user/testfile1.txt#testlink1

-files hdfs://host:fs_port/user/testfile2.txt#testlink2

-archives选项允许用户复制jar包到当前任务的工作路径,并且自动解压jar包。例如,

-archives hdfs://host:fs_port/user/testfile.jar#testlink3

在这个例子中,符号链接testlink3创建在当前任务的工作路径中。符号链接指向存放解压jar包的文件路径。

-archives选项的另外一些例子,input.txt文件有两行数据,定义两个文件的名称,testlink/cache.txt和testlink/cache2.txt。testlink指向文件目录的符号链接,拥有两个文件cache.txt 和cache2.txt。

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input"/user/me/samples/cachefile/input.txt"

-mapper "xargs cat"

-reducer "cat"

-output"/user/me/samples/cachefile/out"

-archives

'hdfs://hadoop-nn1.example.com/user/me/samples/cachefile/cachedir.jar#testlink'

-D mapred.map.tasks=1

-D mapred.reduce.tasks=1

-Dmapred.job.name="Experiment"

$ ls test_jar/

cache.txt cache2.txt

$ jar cvf cachedir.jar -C test_jar/ .

added manifest

adding: cache.txt(in = 30) (out= 29)(deflated 3%)

adding: cache2.txt(in = 37) (out= 35)(deflated 5%)

$ hadoop dfs -put cachedir.jar samples/cachefile

$ hadoop dfs -cat /user/me/samples/cachefile/input.txt

testlink/cache.txt

testlink/cache2.txt

$ cat test_jar/cache.txt

This is just the cache string

$ cat test_jar/cache2.txt

This is just the second cache string

$ hadoop dfs -ls /user/me/samples/cachefile/out

Found 1 items

/user/me/samples/cachefile/out/part-00000  69

$ hadoop dfs -cat /user/me/samples/cachefile/out/part-00000

This is just the cache string

This is just the second cache string


4.4为jobs定义其他的配置变量

用户可以使用-D=定义其他配置变量。例如,

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input myInputDirs

-output myOutputDir

-mapper org.apache.hadoop.mapred.lib.IdentityMapper

-reducer /bin/wc

-D mapred.reduce.tasks=2

选项-D mapred.reduce.tasks=2定义job的reducer为2。


4.5其他支持的选项

Streaming支持hadoop常用命令行选项。支持的参数主要有下面这些:

bin/hadoop command [genericOptions] [commandOptions]

改变本地临时文件夹

-D dfs.data.dir=/tmp

定义其他本地临时文件夹

-D mapred.local.dir=/tmp/local

-D mapred.system.dir=/tmp/system

-D mapred.temp.dir=/tmp/temp

在streaming命令中设置环境变量

-cmdenv EXAMPLE_DIR=/home/example/dictionaries/


5更多的用法实例

5.1自定义将行数据划分为key-value键值对

当mapreduce框架从mapper的stdout中读取每行数据时,它将每行数据划分为key-value键值对。默认情况下,每行数据的第一个tab前的数据是key,剩下的是value(除去tab)。

然而,用户可以自定义该默认设置。用户可以自定义分隔符(除了默认的tab),并且用户也可以定义第n个字符作为kae-value的分隔符。例如,

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input myInputDirs

-output myOutputDir

-mapper org.apache.hadoop.mapred.lib.IdentityMapper

-reducer org.apache.hadoop.mapred.lib.IdentityReducer

-D stream.map.output.field.separator=.

-D stream.num.map.output.key.fields=4

选项-D stream.map.output.field.separator=.定义mapoutput字段的分隔符为.。第四个.前面的是key,后面的是value。如果该行.的个数少于四个,则整行数据就是key,value是空。

同样,也可以设置选项-Dstream.reduce.output.field.separator=SEP和-Dstream.num.reduce.output.fields=NUM来设置reduce输出的key-value。

5.2有用的Partitioner类

Hadoop拥有类KeyFieldBasedPartitioner,对很多应用程序有用。该类在某些key字段的基础上允许mapreduce框架划分map的输出。例如,

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input myInputDirs

-output myOutputDir

-mapper org.apache.hadoop.mapred.lib.IdentityMapper

-reducer org.apache.hadoop.mapred.lib.IdentityReducer

-partitionerorg.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner

-D stream.map.output.field.separator=.

-D stream.num.map.output.key.fields=4

-D map.output.key.field.separator=.

-D mapred.text.key.partitioner.options=-k1,2 
附注:-k1,2 指定对key进行划分后第1 2个域进行划分(上述解释没有找到相关文档,也不属于原文)
-D mapred.reduce.tasks=12

例如,

Output输出(keys)

11.12.1.2

11.14.2.3

11.11.4.1

11.12.1.1

11.14.2.2

划分到3个reducer(前面2个字段作为partition的keys)

11.11.4.1

-----------

11.12.1.2

11.12.1.1

-----------

11.14.2.3

11.14.2.2

Reducer的每个划分内排序(4个字段同时用于排序)

11.11.4.1

-----------

11.12.1.1

11.12.1.2

-----------

11.14.2.2

11.14.2.3


5.3Comparator类

Hadoop拥有类KeyFieldBasedComparator,在很多程序中得到应用。例如,

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input myInputDirs

-output myOutputDir

-mapper org.apache.hadoop.mapred.lib.IdentityMapper

-reducer org.apache.hadoop.mapred.lib.IdentityReducer

-D

mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator

-D stream.map.output.field.separator=.

-D stream.num.map.output.key.fields=4

-D map.output.key.field.separator=.

-D mapred.text.key.comparator.options=-k2,2nr
附注:-k2,2nr 中-k2,2指定key分割后的第2个域进行排序,n 指定使用数字排序,r指定排序结果最后要进行反转
-D mapred.reduce.tasks=12

Map输出(keys)

11.12.1.2

11.14.2.3

11.11.4.1

11.12.1.1

11.14.2.2

Reducer的输出(使用第二个字段进行排序)

11.14.2.3

11.14.2.2

11.12.1.2

11.12.1.1

11.11.4.1


5.4Hadoop Aggregate包(-reduce aggregate选项)

-D mapred.reduce.tasks=12

Python文件AggregatorForKeyCount.py

#!/usr/bin/python

import sys;

def generateLongCountToken(id):
		return "LongValueSum:" + id +"t" +"1"

def main(argv):
		line = sys.stdin.readline();
		try:
				while line:
						line = line[:-1];
						fields = line.split("t");
						print generateLongCountToken(fields[0]);
						line = sys.stdin.readline();
		except "end of file":
				return None

if __name__ == "__main__":
		main(sys.argv)

5.5字段选择

Hadoop有类org.apache.hadoop.mapred.lib.FieldSelectionMapReduce。该类允许用户像unix工具中的cut命令来处理文本数据。该类中的Map函数将每个输入的键值对作为字段列表,用户可以自定义字段分隔符。用户可以选择字段列表作为map的输出的key,其他的字段列表作为map的输出的value。Reduce函数与此类似。

$HADOOP_HOME/bin/hadoop jar $HADOOP_HOME/hadoop-streaming.jar

-input myInputDirs

-output myOutputDir

-mapperorg.apache.hadoop.mapred.lib.FieldSelectionMapReduce

-reducerorg.apache.hadoop.mapred.lib.FieldSelectionMapReduce

-partitionerorg.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner

-D map.output.key.field.separa=.

-D mapred.text.key.partitioner.options=-k1,2

-D mapred.data.field.separator=.

-D map.output.key.value.fields.spec=6,5,1-3:0-

-D reduce.output.key.value.fields.spec=0-2:5-

-D mapred.reduce.tasks=12

5.6 mapred尝试任务失败次数控制及map任务失败率控制

-D mapred.map.max.attempts="3" \                                                                                  
-D mapred.reduce.max.attempts="3" \                                                                               
-D mapred.max.map.failures.percent="1" \  设置map任务失败率容忍率

5.7 mapred限制java读取数据行的最大长度(防止mapred程序执行时进度停滞且报heatbeat错误):
-D  mapred.linerecordreader.maxlength = 409600



你可能感兴趣的:(hadoop)